texlive[48771] trunk: luaotfload (26sep18)

commits+karl at tug.org commits+karl at tug.org
Wed Sep 26 22:50:34 CEST 2018


Revision: 48771
          http://tug.org/svn/texlive?view=revision&revision=48771
Author:   karl
Date:     2018-09-26 22:50:34 +0200 (Wed, 26 Sep 2018)
Log Message:
-----------
luaotfload (26sep18)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua
    trunk/Master/texmf-dist/doc/luatex/luaotfload/NEWS
    trunk/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf
    trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.1
    trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf
    trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.5
    trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.man5.pdf
    trunk/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-gen.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-afk.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-cff.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-cid.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ini.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-map.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-one.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-onr.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-osd.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ota.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otc.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oti.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otj.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otl.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oto.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otr.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oup.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-tfm.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ttf.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-enc.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-ext.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-syn.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-file.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-io.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-math.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-string.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-table.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-fil.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-characters.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/luatex/luaotfload/README.md
    trunk/Master/texmf-dist/doc/luatex/luaotfload/filegraph.tex
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.tex
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.pdf
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.tex
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.tex
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst
    trunk/Master/texmf-dist/source/luatex/luaotfload/fontloader-reference-load-order.lua
    trunk/Master/texmf-dist/source/luatex/luaotfload/fontloader-reference-load-order.tex
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2018-09-24.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-effects.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-italics.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-ligatures.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-tex.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ott.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-vfc.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-def.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-gbn.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-lig.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-mis.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua

Removed Paths:
-------------
    trunk/Master/texmf-dist/doc/luatex/luaotfload/README
    trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.pdf
    trunk/Master/texmf-dist/doc/luatex/luaotfload/valgrind-kpse-suppression.sup
    trunk/Master/texmf-dist/scripts/luaotfload/mkcharacters
    trunk/Master/texmf-dist/scripts/luaotfload/mkglyphlist
    trunk/Master/texmf-dist/scripts/luaotfload/mkimport
    trunk/Master/texmf-dist/scripts/luaotfload/mkstatus
    trunk/Master/texmf-dist/scripts/luaotfload/mktests
    trunk/Master/texmf-dist/source/luatex/luaotfload/Makefile
    trunk/Master/texmf-dist/source/luatex/luaotfload/filegraph.dot
    trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload-latex.tex
    trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex
    trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload-tool.rst
    trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload.conf.rst
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2017-02-11.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics.tex
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-gbn.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-demo-vf-1.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts.tex
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-languages.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-languages.tex
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-math.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-math.tex
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-mplib.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-mplib.tex
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-plain.tex
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-preprocessor-test.tex
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-preprocessor.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-preprocessor.tex
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-swiglib-test.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-swiglib-test.tex
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-swiglib.lua
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-swiglib.tex
    trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-test.tex

Modified: trunk/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Build/source/texk/texlive/linked_scripts/luaotfload/luaotfload-tool.lua	2018-09-26 20:50:34 UTC (rev 48771)
@@ -2,13 +2,13 @@
 -----------------------------------------------------------------------
 --         FILE:  luaotfload-tool.lua
 --  DESCRIPTION:  database functionality
--- REQUIREMENTS:  luaotfload 2.8
+-- REQUIREMENTS:  luaotfload 2.9
 --       AUTHOR:  Khaled Hosny, Élie Roux, Philipp Gesang
 --      LICENSE:  GPL v2.0
 -----------------------------------------------------------------------
 
 luaotfload                     = luaotfload or { }
-local version                  = "2.8"
+local version                  = "2.9"
 luaotfload.version             = version
 luaotfload.min_luatex_version  = { 0, 95, 0 }
 luaotfload.self                = "luaotfload-tool"

Modified: trunk/Master/texmf-dist/doc/luatex/luaotfload/NEWS
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/NEWS	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/NEWS	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,5 +1,17 @@
 Change History
 --------------
+2018-09-21 luaotfload v2.9 
+    * added various testfiles for the l3build system/travis tests to the github repository
+    * solved a bug regarding directions https://github.com/u-fischer/lua-font-pond/issues/12
+    * adapted luaotfload-letterspace to new fontloader
+    * solved the case problem see https://github.com/u-fischer/lua-font-pond/issues/6
+    * Fix parsing of font.conf see https://github.com/lualatex/luaotfload/pull/420
+    * imported new versions of the context files - fontloader is compatible with luatex 1.08 again
+    * adapted the files list 
+    * created a luaotfload-filelist.lua which describes the files of the package
+    * removed some not functional files 
+    * adapted mkstatus to use the new file list.
+    
 2017-01-29, luaotfload v2.8:
     * Latest fontloader code.
     * Support for Luatex 1.0.

Deleted: trunk/Master/texmf-dist/doc/luatex/luaotfload/README
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/README	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/README	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,97 +0,0 @@
-*******************************************************************************
-                            The Luaotfload Package
-*******************************************************************************
-
-Luaotfload is an adaptation of the ConTeXt font loading system for the Plain
-and LaTeX formats. It allows OpenType fonts to be loaded with font features
-accessible using an extended font request syntax while providing compatibility
-with XeTeX. By indexing metadata in a database it facilitates loading fonts by
-their proper names instead of file names.
-
-Luaotfload may be loaded in Plain LuaTeX with "\input luaotfload.sty" and in
-LuaLaTeX with "\usepackage{luaotfload}". LuaLaTeX users may be interested in
-the fontspec package which provides a high-level interface to the functionality
-provided by this package.
-
-Please see the documentation luaotfload.pdf for more information.
-
-This package is developed by the LuaLaTeX dev team on
-<http://github.com/lualatex/luaotfload>. Please report bugs to the issue
-tracker there.
-
-The development for LuaLaTeX is discussed on the lualatex-dev mailing list. See
-<http://www.tug.org/mailman/listinfo/lualatex-dev> for details.
-
-
-Responsible Persons
--------------------------------------------------------------------------------
-The following people have contributed to this package.
-
-Khaled Hosny             <khaledhosny at eglug.org>
-Elie Roux                <elie.roux at telecom-bretagne.eu>
-Will Robertson           <will.robertson at latex-project.org>
-Philipp Gesang           <phg at phi-gamma.net>
-Dohyun Kim               <nomosnomos at gmail.com>
-Reuben Thomas            <https://github.com/rrthomas>
-Joseph Wright            <joseph.wright at morningstar2.co.uk>
-Manuel Pégourié-Gonnard  <mpg at elzevir.fr>
-Olof-Joachim Frahm       <olof at macrolet.net>
-Patrick Gundlach         <gundlach at speedata.de>
-Philipp Stephani         <st_philipp at yahoo.de>
-David Carlisle           <d.p.carlisle at gmail.com>
-Yan Zhou                 @zhouyan
-
-Installation
--------------------------------------------------------------------------------
-
-Here are the recommended installation methods (preferred first).
-
-1. If you are using TeX Live 2008 or later, use 'tlmgr install luaotfload'.
-   Alternatively, try your (TeX or Linux) distribution's package management
-   system.
-
-2. a. Download luaotfload.tds.zip from CTAN.
-   b. Unzip it at the root of one or your TDS trees.
-   c. You may need to update some filename database after, see your TeX
-      distribution's manual for details.
-
-3. a. Grab the sources from CTAN or github.
-   b. Run 'make install DESTDIR=/path/to/texmf'.
-   c. See 2c.
-
-4. Try to figure it out by looking at the Makefile and comments in the sources.
-
-Prerequisites
--------------------------------------------------------------------------------
-
-You need GNU make to use the Makefile. The executable may be called "gmake" on
-your system.
-
-Typesetting the documentation requires LuaTeX and GraphViz. The Docutils are
-needed to generate the manpage.
-
-License
--------------------------------------------------------------------------------
-
-The luaotfload bundle, as a derived work of ConTeXt, is distributed under the
-GNU GPLv2 license:
-
-   <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
-
-This license requires the license itself to be distributed with the work. For
-its full text see the documentation in luaotfload.pdf.
-
-
-                                  DISCLAIMER
-
-        This program is free software; you can redistribute it and/or
-        modify it under the terms of the GNU General Public License
-        as published by the Free Software Foundation; version 2.
-
-        This program is distributed in the hope that it will be useful,
-        but WITHOUT ANY WARRANTY; without even the implied warranty of
-        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-        GNU General Public License for more details.
-
-        See headers of each source file for copyright details.
-

Added: trunk/Master/texmf-dist/doc/luatex/luaotfload/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/README.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/README.md	2018-09-26 20:50:34 UTC (rev 48771)
@@ -0,0 +1,103 @@
+# The Luaotfload Package
+
+VERSION: 2.9
+
+DATE: 2018-09-24
+
+
+## Description
+
+Luaotfload is an adaptation of the ConTeXt font loading system for the Plain
+and LaTeX formats. It allows OpenType fonts to be loaded with font features
+accessible using an extended font request syntax while providing compatibility
+with XeTeX. By indexing metadata in a database it facilitates loading fonts by
+their proper names instead of file names.
+
+Luaotfload may be loaded in Plain LuaTeX with "\input luaotfload.sty" and in
+LuaLaTeX with "\usepackage{luaotfload}". LuaLaTeX users may be interested in
+the fontspec package which provides a high-level interface to the functionality
+provided by this package.
+
+Please see the documentation luaotfload.pdf for more information.
+
+## Maintenance
+
+This package is currently maintained at 
+<https://github.com/u-fischer/luaotfload>. 
+ 
+Issues can be reported at the issue tracker or at the old issue tracker on 
+<http://github.com/lualatex/luaotfload>. 
+
+The development for LuaLaTeX is discussed on the lualatex-dev mailing list. See
+<http://www.tug.org/mailman/listinfo/lualatex-dev> for details.
+
+
+## Responsible Persons
+
+The following people have contributed to this package.
+
+- Khaled Hosny             <khaledhosny at eglug.org>
+- Elie Roux                <elie.roux at telecom-bretagne.eu>
+- Will Robertson           <will.robertson at latex-project.org>
+- Philipp Gesang           <phg at phi-gamma.net>
+- Dohyun Kim               <nomosnomos at gmail.com>
+- Reuben Thomas            <https://github.com/rrthomas>
+- Joseph Wright            <joseph.wright at morningstar2.co.uk>
+- Manuel Pégourié-Gonnard  <mpg at elzevir.fr>
+- Olof-Joachim Frahm       <olof at macrolet.net>
+- Patrick Gundlach         <gundlach at speedata.de>
+- Philipp Stephani         <st_philipp at yahoo.de>
+- David Carlisle           <d.p.carlisle at gmail.com>
+- Yan Zhou                 @zhouyan
+- Ulrike Fischer           <fischer at troubleshooting-tex.de>
+- Marcel Krüger            <https://github.com/zauguin> 
+
+## Installation
+
+1.  Install the current version with the package management tools of your TeX system.
+    If you want to install manually: there is a tds-zip file which can be unpacked in a texmf tree. 
+
+2.  If you want to try the development version download the texmf folder in the development branch. 
+    at <https://github.com/u-fischer/luaotfload>
+    
+3.  Manual installation:
+    * luaotfload-tool.lua belongs in scripts/luatex/luaotfload
+    * fontloader-reference-load-order.tex and fontloader-reference-load-order.lua are source files and can got in source or doc
+    * the other lua-files and the sty belong in tex/luatex/luaotfload
+    * luaotfload.conf.5 and luaotfload-tool.1 belong in doc/man
+    * the rest in doc/luatex/luaotfload  
+    
+## Documentation
+
+* The main documentation is luaotfload-latex.pdf. 
+* luaotfload.conf.5 and luaotfload-tool.1 are man-files, their sources are the rst-files. 
+* README.md, NEWS and COPYING contain what their name says.
+* The rest are input files. 
+
+
+    
+
+## License
+
+The luaotfload bundle, as a derived work of ConTeXt, is distributed under the
+GNU GPLv2 license:
+
+   <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
+
+This license requires the license itself to be distributed with the work. For
+its full text see the documentation in luaotfload.pdf.
+
+
+##  DISCLAIMER
+
+        This program is free software; you can redistribute it and/or
+        modify it under the terms of the GNU General Public License
+        as published by the Free Software Foundation; version 2.
+
+        This program is distributed in the hope that it will be useful,
+        but WITHOUT ANY WARRANTY; without even the implied warranty of
+        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+        GNU General Public License for more details.
+
+        See headers of each source file for copyright details.
+


Property changes on: trunk/Master/texmf-dist/doc/luatex/luaotfload/README.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/doc/luatex/luaotfload/filegraph.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/filegraph.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/filegraph.tex	2018-09-26 20:50:34 UTC (rev 48771)
@@ -0,0 +1,265 @@
+% !Mode:: "TeX:EN:UTF-8:Main"
+%created with by @marmot 14.09.2018
+%
+\documentclass[border=3.14mm,tikz]{standalone}
+\usetikzlibrary{fit,matrix,positioning,arrows.meta,decorations.text,shapes.callouts}
+\pgfdeclarelayer{background}
+\pgfdeclarelayer{container}
+\pgfdeclarelayer{foreground}
+\pgfsetlayers{container,background,main,foreground}
+\usepackage {fontspec}
+\usepackage {unicode-math}
+\usepackage{tikzmarmots,tikzducks}
+
+\setmainfont[
+% Numbers     = OldStyle, %% buggy with font cache
+  Ligatures   = TeX,
+  BoldFont    = {Linux Libertine O Bold},
+  ItalicFont  = {Linux Libertine O Italic},
+  SlantedFont = {Linux Libertine O Italic},
+]{Linux Libertine O}
+\setmonofont[Ligatures=TeX,Scale=MatchLowercase]{InconsolataN-Regular.otf}
+%setsansfont[Ligatures=TeX]{Linux Biolinum O}
+\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{Iwona Medium}
+
+\usepackage{luacode}
+\begin{luacode}
+require("luaotfload-filelist.lua")
+
+function printctxfontlist ()
+ t= luaotfload.filelist.selectctxfontentries (luaotfload.filelist.data)
+ for i,v in ipairs (t) do
+  tex.sprint("\\mbox{"..v.name..v.ext.."} ")
+ end
+end
+
+function printctxlibslist ()
+ t= luaotfload.filelist.selectctxlibsentries (luaotfload.filelist.data)
+ local rowcnt = 0
+ local sep = "&"
+ for i,v in ipairs (t) do
+  rowcnt = rowcnt + 1
+  if rowcnt % 4 == 0 then sep = "\\\\" else sep = "&" end
+  tex.sprint("\\mbox{"..v.name..v.ext.."}".. sep)
+ end
+end
+
+function printctxgenericlist ()
+ t= luaotfload.filelist.selectctxgeneusedentries (luaotfload.filelist.data)
+ local rowcnt = 0
+ local sep = "&"
+ for i,v in ipairs (t) do
+  rowcnt = rowcnt + 1
+  if rowcnt % 2 == 0 then sep = "\\\\" else sep = "&" end
+  tex.sprint("\\mbox{"..v.ctxpref..v.name..v.ext.."}".. sep)
+ end
+end
+
+
+function printlibrarylist ()
+ t = luaotfload.filelist.selectlollibentries (luaotfload.filelist.data)
+ local rowcnt = 0
+ local sep = "&"
+ for i,v in ipairs (t) do
+  rowcnt = rowcnt + 1
+  if rowcnt % 2 == 0 then sep = "\\\\" else sep = "&" end
+  tex.sprint("\\mbox{"..v.gitpref..v.name..v.ext.."}".. sep)
+ end
+end
+
+function printscriptlist ()
+ t = luaotfload.filelist.selectlolscrentries (luaotfload.filelist.data)
+ for i,v in ipairs ( t ) do
+  if v.kind == 8 then
+    tex.sprint( v.name .."\\\\")
+  end
+ end
+end
+
+\end{luacode}
+\begin{document}
+\begin{tikzpicture}[rounded corners,basic/.style={inner
+sep=9pt,font=\ttfamily,align=center}]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% text nodes
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% m1
+\matrix [matrix of nodes,font=\ttfamily,nodes={anchor=base west},
+label={[name=mL1,font=\itshape]above:Luaotfload Libraries}] (m1)
+{%
+%<<<<<<<<<<<<<<<<
+\directlua{printlibrarylist()}
+%>>>>>>>>>>>>>>>>
+};
+% m2	
+\node[right=4.2cm of m1,fill=gray!20,draw=gray!30,dashed,basic] (m2) {luaotfload-blacklist.cnf};	
+% m3
+\matrix [below=2cm of m1,matrix of nodes,font=\ttfamily,nodes={anchor=base west},
+label={[name=mL3,font=\itshape,anchor=south]above:Lualibs -- Lua Libraries from Context}] (m3)
+{%
+%<<<<<<<<<<<<<<<<
+\directlua{printctxlibslist ()}
+%>>>>>>>>>>>>>>>>
+};
+% m4	
+\node[left=2cm of m3,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m4) {luaotfload-main.lua};	
+% m5
+\node[fill=gray!20,draw=gray!30,dashed,basic,inner sep=6mm,anchor=south west] at (m3.south -|
+m2.west)(m5){%
+%<<<<<<<<<<<<<<<<
+luaotfload-names.lua.gz\\
+luaotfload-names.luc
+%>>>>>>>>>>>>>>>>
+};	
+% m6
+\node[below=3cm of m3,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m6){luaotfload-init.lua};	
+% m7
+\node[above right=0.5cm and 2.5cm of m6,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m7){luaotfload-log.lua};	
+% m8
+\matrix [below left=1cm and 2cm of m6,matrix of nodes,font=\ttfamily,
+row sep=5mm,
+nodes={inner sep=3mm,fill=orange!10,rounded corners},
+label={[name=mL8,font=\it]above:Fontloader}] (m8)
+{%
+%<<<<<<<<<<<<<<<<
+fontloader-basics-gen.lua\\
+fontloader-YY-MM-DD.lua\\
+%<<<<<<<<<<<<<<<<
+};
+% m9
+\node [below right=1cm and 2cm of m6,font=\ttfamily,
+inner sep=3mm,text width=7.3cm,align=left,
+label={[name=mL9,font=\itshape]Font and Node Libraries from Context}] (m9)
+{\spaceskip=1.5em \raggedright
+%%<<<<<<<<<<<<<<<<
+\directlua{printctxfontlist()}
+%>>>>>>>>>>>>>>>>
+};
+% m10
+\node [below=1cm of m9,font=\ttfamily,
+inner sep=3mm,text width=7.3cm,align=center,
+label={[name=mL10,font=\itshape]Font Loader (LuaTeX-Fonts)}] (m10)
+{\tabcolsep=0.5em
+ \begin{tabular}{@{}ll@{}}
+%<<<<<<<<<<<<<<<<
+\directlua{printctxgenericlist ()}
+%>>>>>>>>>>>>>>>>
+ \end{tabular}
+};
+% m11
+\node [above=1cm of m9] (m11) {Merged libraries};
+% m12
+\matrix [below=4cm of m6,xshift=-1cm,matrix of nodes,font=\ttfamily,
+row sep=5mm,
+nodes={inner sep=3mm,fill=gray!10,rounded corners,text width=3cm,align=center},
+label={[name=mL12,font=\sffamily]above:Standalone scripts}] (m12)
+{%
+%<<<<<<<<<<<<<<<<
+\directlua{printscriptlist ()}
+%>>>>>>>>>>>>>>>>
+};
+% m13
+\node[below=1.2cm of m10,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm]	(m13)
+{%
+%<<<<<<<<<<<<<<<<
+luaotfload-glyphlist.lua
+%>>>>>>>>>>>>>>>>
+};
+% m14
+\node[below=0.8cm of m13,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm]	(m14)
+{%
+%<<<<<<<<<<<<<<<<
+luaotfload-characters.lua
+%>>>>>>>>>>>>>>>>
+};
+% m15
+\node[below=3cm of m8,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm]	
+(m15) {%
+%<<<<<<<<<<<<<<<<
+luaotfload-tool.lua
+%>>>>>>>>>>>>>>>>
+};
+% m16
+\node[below=1cm of m15,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm]	
+(m16) {%
+%<<<<<<<<<<<<<<<<
+luaotfload-diagnostics.lua
+%>>>>>>>>>>>>>>>>
+};
+% m17
+\node[below=2cm of m16,xshift=3cm,fill=gray!20,draw=gray!30,dashed,basic,inner sep=6pt]	
+(m17) {%
+%<<<<<<<<<<<<<<<<
+luaotfload-status.lua
+%>>>>>>>>>>>>>>>>
+};
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% envelopes
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{pgfonlayer}{background}
+%M1
+\node[fill=gray!10,fit=(m1)(mL1),rounded corners=0](mF1){};
+%M3
+\node[fill=blue!10,fit=(m3)(mL3),rounded corners=0](mF3){};
+%M9
+\node[fill=purple!10,fit=(m9)(mL9)](mF9){};
+%M10
+\node[fill=purple!10,fit=(m10)(mL10)](mF10){};
+\end{pgfonlayer}
+\begin{pgfonlayer}{container}
+%M1
+\node[fill=gray!20,fit=(mF1)](M1){};
+%M3
+\node[fill=blue!20,fit=(mF3)](M3){};
+%M8
+\node[fill=orange!20,fit=(m8)(mL8)](mF8){};
+%M11
+\node[fill=purple!20,fit=(m11)(mF9)(mF10)](M11){};
+%M11
+\node[top color=gray!40,bottom color=red!60!black,fit=(mL12)(m12)](M12){};
+\end{pgfonlayer}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% arrows
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{scope}[font=\sffamily,>={Triangle[open]},annotate/.style={postaction={decorate,decoration={text along path,text
+align=center,raise=2pt,text={|\sffamily| #1}}}}]
+\draw[->,annotate=luaotfload-database.lua] (M1) -- (m2);
+\draw[->,annotate=main()] (m4) -- (M1);
+\draw[->] (m4) -- (M3);
+\draw[->,annotate=luaotfload-database.lua] (M1.-15) to[out=0,in=90] (m5);
+\draw[->,annotate=main()] (m4) to[out=-70,in=120] (m6);
+\draw[->,annotate=init{{\_}}early()] (m6) to[out=45,in=190] (m7);
+\draw[<-,annotate=init{{\_}}early()] (m8-1-1) to[in=-150,out=0] (m6);
+\draw[<-,annotate=init{{\_}}main()] (m8-2-1) to[in=-100,out=4] (m6);
+\draw[->,annotate=unmerged] (m6) to[out=0,in=180] (mF9.150);
+\draw[->,dashed,annotate=merged] (m8-2-1) to[out=0,in=180] (mF9.170);
+\draw[->,dashed,annotate=pulls] (m12-1-1) to[out=0,in=180] (mF9);
+\draw[->,dashed,annotate=pulls] (m12-1-1) to[out=0,in=180] (mF10);
+\draw[<-,dashed,annotate=merges] (m8-2-1) to[out=-45,in=180] (m12-1-1);
+\draw[->] (mF10) to node[midway,left]{luatex-fonts-enc.lua} (m13);
+\draw[->] (mF10.-30) to[out=-60,in=50]node[pos=0.3,right]{ luaotfload-auxiliary.lua} (m14.15);
+\draw[->,dashed,annotate=generates from glyphlist.txt] (m12-2-1) to[out=0,in=180] (m13);
+\draw[->,dashed,annotate=generates from Context's char-def.lua] (m12-3-1) to[out=0,in=180] (m14);
+\draw[->,dashed,annotate={{-}{-}update}] (m15) to[out=130,in=-80] ++ (-3.5,4)
+to[out=100,in=-110] ++ (0,2)
+to[out=70,in=-165] (m5);
+\draw[->,annotate=version information] (m15) to[out=-170,in=90] ++(-3.5,-3)
+to[out=-90,in=180] (m17);
+\draw[->] (m15) -- node[midway,right]{-\,-diagnose} (m16);
+\draw[->,annotate=hash files] (m16) -- (m17);
+\draw[<-,dashed,annotate=generates from distribution files] (m17)
+to[out=0,in=-135] ++(5,1) to[out=45,in=0] (m12-4-1);
+\end{scope}
+
+\begin{scope}[shift={([xshift=2cm,yshift=-3cm]current bounding box.north west)}]
+\marmot;
+\duck[invisible];
+\node[anchor=south,draw,text width=3cm,shape=rectangle callout,font=\sffamily\scriptsize,align=center]
+at ([yshift=1cm,xshift=-0.5cm]bill)
+{It looks complicated\\ because it is complicated!};
+%
+\end{scope}
+
+\end{tikzpicture}
+\end{document} 
\ No newline at end of file


Property changes on: trunk/Master/texmf-dist/doc/luatex/luaotfload/filegraph.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf	2018-09-26 20:50:34 UTC (rev 48771)

Property changes on: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.tex	2018-09-26 20:50:34 UTC (rev 48771)
@@ -0,0 +1,707 @@
+\documentclass[a4paper]{article}
+% generated by Docutils <http://docutils.sourceforge.net/>
+% rubber: set program xelatex
+\usepackage{fontspec}
+% \defaultfontfeatures{Scale=MatchLowercase}
+% straight double quotes (defined T1 but missing in TU):
+\ifdefined \UnicodeEncodingName
+  \DeclareTextCommand{\textquotedbl}{\UnicodeEncodingName}{%
+    {\addfontfeatures{RawFeature=-tlig,Mapping=}\char34}}%
+\fi
+\usepackage{ifthen}
+\usepackage{alltt}
+\setcounter{secnumdepth}{0}
+\usepackage{longtable,ltcaption,array}
+\setlength{\extrarowheight}{2pt}
+\newlength{\DUtablewidth} % internal use in tables
+\usepackage{tabularx}
+
+%%% Custom LaTeX preamble
+% Linux Libertine (free, wide coverage, not only for Linux)
+\setmainfont{Linux Libertine O}
+\setsansfont{Linux Biolinum O}
+\setmonofont[HyphenChar=None,Scale=MatchLowercase]{DejaVu Sans Mono}
+
+%%% User specified packages and stylesheets
+
+%%% Fallback definitions for Docutils-specific commands
+
+% providelength (provide a length variable and set default, if it is new)
+\providecommand*{\DUprovidelength}[2]{
+  \ifthenelse{\isundefined{#1}}{\newlength{#1}\setlength{#1}{#2}}{}
+}
+
+% docinfo (width of docinfo table)
+\DUprovidelength{\DUdocinfowidth}{0.9\linewidth}
+
+% subtitle (in document title)
+\providecommand*{\DUdocumentsubtitle}[1]{{\large #1}}
+% hyperlinks:
+\ifthenelse{\isundefined{\hypersetup}}{
+  \usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
+  \usepackage{bookmark}
+  \urlstyle{same} % normal text font (alternatives: tt, rm, sf)
+}{}
+\hypersetup{
+  pdftitle={luaotfload.conf},
+}
+
+\title{luaotfload.conf%
+  \label{luaotfload-conf}%
+  \\ % subtitle%
+  \DUdocumentsubtitle{Luaotfload configuration file}%
+  \label{luaotfload-configuration-file}}
+\author{}
+\date{}
+
+%%% Body
+\begin{document}
+\maketitle
+
+% Docinfo
+\begin{center}
+\begin{tabularx}{\DUdocinfowidth}{lX}
+\textbf{Date}: &
+	2018-09-21 \\
+\textbf{Copyright}: &
+	GPL v2.0 \\
+\textbf{Version}: &
+	2.9 \\
+\textbf{Manual section}: &
+5
+\\
+\textbf{Manual group}: &
+text processing
+\\
+\end{tabularx}
+\end{center}
+
+
+\section{SYNOPSIS%
+  \label{synopsis}%
+}
+
+\begin{itemize}
+\item \textbf{./luaotfload\{.conf,rc\}}
+
+\item \textbf{XDG\_CONFIG\_HOME/luaotfload/luaotfload\{.conf,rc\}}
+
+\item \textbf{\textasciitilde{}/.luaotfloadrc}
+\end{itemize}
+
+
+\section{DESCRIPTION%
+  \label{description}%
+}
+
+The file \texttt{luaotfload.conf} contains configuration options for
+\emph{Luaotfload}, a font loading and font management component for LuaTeX.
+
+
+\section{EXAMPLE%
+  \label{example}%
+}
+
+A small Luaotfload configuration file with few customizations could
+look as follows:
+
+\begin{quote}
+\begin{alltt}
+[db]
+    formats = afm,ttf
+    compress = false
+
+[misc]
+    termwidth = 60
+
+[run]
+    log-level = 6
+\end{alltt}
+\end{quote}
+
+This will make Luaotfload ignore all font files except for PostScript
+binary fonts with a matching AFM file, and Truetype fonts. Also, an
+uncompressed index file will be dumped which is going to be much larger
+than the default gzip’ed index. The terminal width
+is truncated to 60 characters which influences the verbose output
+during indexing. Finally, the verbosity is increased greatly: each font
+file being processed will be printed to the stdout on a separate line,
+along with lots of other information.
+
+To observe the difference in behavior, save above snippet to
+\texttt{./luaotfload.conf} and update the font index:
+
+\begin{quote}
+\begin{alltt}
+luaotfload-tool --update --force
+\end{alltt}
+\end{quote}
+
+The current configuration can be written to disk using
+\textbf{luaotfload-tool}:
+
+\begin{quote}
+\begin{alltt}
+luaotfload-tool --dumpconf > luaotfload.conf
+\end{alltt}
+\end{quote}
+
+The result can itself be used as a configuration file.
+
+
+\section{SYNTAX%
+  \label{syntax}%
+}
+
+The configuration file syntax follows the common INI format. For a more
+detailed description please refer to the section “CONFIGURATION FILE”
+of \textbf{git-config}(1). A brief list of rules is given below:
+
+\begin{quote}
+\begin{itemize}
+\item Blank lines and lines starting with a semicolon (\texttt{;}) are ignored.
+
+\item A configuration file is partitioned into sections that are declared
+by specifying the section title in brackets on a separate line:
+
+\begin{quote}
+\begin{alltt}
+[some-section]
+... section content ...
+\end{alltt}
+\end{quote}
+
+\item Sections consist of one or more variable assignments of the form
+\texttt{variable-name = value}  E. g.:
+
+\begin{quote}
+\begin{alltt}
+[foo]
+    bar = baz
+    quux = xyzzy
+    ...
+\end{alltt}
+\end{quote}
+
+\item Section and variable names may contain only uppercase and lowercase
+letters as well as dashes (\texttt{-}).
+\end{itemize}
+\end{quote}
+
+
+\section{VARIABLES%
+  \label{variables}%
+}
+
+Variables in belong into a configuration section and their values must
+be of a certain type. Some of them have further constraints. For
+example, the “color callback” must be a string of one of the values
+\texttt{post\_linebreak\_filter}, \texttt{pre\_linebreak\_filter}, or
+\texttt{pre\_output\_filter}, defined in the section \emph{run} of the
+configuration file.
+
+Currently, the configuration is organized into four sections:
+
+\begin{description}
+\item[{db}] \leavevmode 
+Options relating to the font index.
+
+\item[{misc}] \leavevmode 
+Options without a clearly defined category.
+
+\item[{paths}] \leavevmode 
+Path and file name settings.
+
+\item[{run}] \leavevmode 
+Options controlling runtime behavior of Luaotfload.
+
+\end{description}
+
+The list of valid variables, the sections they are part of and their
+type is given below. Types represent Lua types that the values must be
+convertible to; they are abbreviated as follows: \texttt{s} for the \emph{string}
+type, \texttt{n} for \emph{number}, \texttt{b} for \emph{boolean}. A value of \texttt{nil} means
+the variable is unset.
+
+
+\subsection{Section \texttt{db}%
+  \label{section-db}%
+}
+
+\setlength{\DUtablewidth}{\linewidth}
+\begin{longtable*}[c]{|p{0.249\DUtablewidth}|p{0.110\DUtablewidth}|p{0.331\DUtablewidth}|}
+\hline
+
+variable
+ & 
+type
+ & 
+default
+ \\
+\hline
+
+compress
+ & 
+b
+ & 
+\texttt{true}
+ \\
+\hline
+
+designsize-dimen
+ & 
+b
+ & 
+\texttt{bp}
+ \\
+\hline
+
+formats
+ & 
+s
+ & 
+\texttt{\textquotedbl{}otf,ttf,ttc\textquotedbl{}}
+ \\
+\hline
+
+max-fonts
+ & 
+n
+ & 
+\texttt{2\textasciicircum{}51}
+ \\
+\hline
+
+scan-local
+ & 
+b
+ & 
+\texttt{false}
+ \\
+\hline
+
+skip-read
+ & 
+b
+ & 
+\texttt{false}
+ \\
+\hline
+
+strip
+ & 
+b
+ & 
+\texttt{true}
+ \\
+\hline
+
+update-live
+ & 
+b
+ & 
+\texttt{true}
+ \\
+\hline
+\end{longtable*}
+
+The flag \texttt{compress} determines whether the font index (usually
+\texttt{luaotfload-names.lua{[}.gz{]}} will be stored in compressed forms.
+If unset it is equivalent of passing \texttt{--no-compress} to
+\textbf{luaotfload-tool}. Since the file is only created for convenience
+and has no effect on the runtime behavior of Luaotfload, the flag
+should remain set. Most editors come with zlib support anyways.
+
+The setting \texttt{designsize-dimen} applies when looking up fonts from
+families with design sizes. In Opentype, these are specified as
+“decipoints” where one decipoint equals ten DTP style “big points”.
+When indexing fonts these values are converted to \texttt{sp}. In order to
+treat the values as though they were specified in TeX points or Didot
+points, set \texttt{designsize-dimen} to \texttt{pt} or \texttt{dd}.
+
+The list of \texttt{formats} must be a comma separated sequence of strings
+containing one or more of these elements:
+
+\begin{itemize}
+\item \texttt{otf}               (OpenType format),
+
+\item \texttt{ttf} and \texttt{ttc}       (TrueType format),
+
+\item \texttt{afm}               (Adobe Font Metrics),
+\end{itemize}
+
+It corresponds loosely to the \texttt{--formats} option to
+\textbf{luaotfload-tool}. Invalid or duplicate members are ignored; if the
+list does not contain any useful identifiers, the default list
+\texttt{\textquotedbl{}otf,ttf,ttc\textquotedbl{}} will be used.
+
+The variable \texttt{max-fonts} determines after processing how many font
+files the font scanner will terminate the search. This is useful for
+debugging issues with the font index and has the same effect as the
+option \texttt{--max-fonts} to \textbf{luaotfload-tools}.
+
+The \texttt{scan-local} flag, if set, will incorporate the current working
+directory as a font search location. NB: This will potentially slow
+down document processing because a font index with local fonts will not
+be saved to disk, so these fonts will have to be re-indexed whenever
+the document is built.
+
+The \texttt{skip-read} flag is only useful for debugging: It makes
+Luaotfload skip reading fonts. The font information for rebuilding the
+index is taken from the presently existing one.
+
+Unsetting the \texttt{strip} flag prevents Luaotfload from removing data
+from the index that is only useful when processing font files. NB: this
+can increase the size of the index files significantly and has no
+effect on the runtime behavior.
+
+If \texttt{update-live} is set, Luaotfload will reload the database if it
+cannot find a requested font. Those who prefer to update manually using
+\textbf{luaotfload-tool} should unset this flag. This option does not affect
+rebuilds due to version mismatch.
+
+
+\subsection{Section \texttt{default-features}%
+  \label{section-default-features}%
+}
+
+By default Luaotfload enables \texttt{node} mode and picks the default font
+features that are prescribed in the OpenType standard. This behavior
+may be overridden in the \texttt{default-features} section. Global defaults
+that will be applied for all scripts can be set via the \texttt{global}
+option, others by the script they are to be applied to. For example,
+a setting of
+
+\begin{quote}
+\begin{alltt}
+[default-features]
+    global = mode=base,color=0000FF
+    dflt   = smcp,onum
+\end{alltt}
+\end{quote}
+
+would force \emph{base} mode, tint all fonts blue and activate small
+capitals and text figures globally. Features are specified as a comma
+separated list of variables or variable-value pairs. Variables without
+an explicit value are set to \texttt{true}.
+
+
+\subsection{Section \texttt{misc}%
+  \label{section-misc}%
+}
+
+\setlength{\DUtablewidth}{\linewidth}
+\begin{longtable*}[c]{|p{0.191\DUtablewidth}|p{0.110\DUtablewidth}|p{0.307\DUtablewidth}|}
+\hline
+
+variable
+ & 
+type
+ & 
+default
+ \\
+\hline
+
+statistics
+ & 
+b
+ & 
+\texttt{false}
+ \\
+\hline
+
+termwidth
+ & 
+n
+ & 
+\texttt{nil}
+ \\
+\hline
+
+version
+ & 
+s
+ & 
+<Luaotfload version>
+ \\
+\hline
+\end{longtable*}
+
+With \texttt{statistics} enabled, extra statistics will be collected during
+index creation and appended to the index file. It may then be queried
+at the Lua end or inspected by reading the file itself.
+
+The value of \texttt{termwidth}, if set, overrides the value retrieved by
+querying the properties of the terminal in which Luatex runs. This is
+useful if the engine runs with \texttt{shell\_escape} disabled and the actual
+terminal dimensions cannot be retrieved.
+
+The value of \texttt{version} is derived from the version string hard-coded
+in the Luaotfload source. Override at your own risk.
+
+
+\subsection{Section \texttt{paths}%
+  \label{section-paths}%
+}
+
+\setlength{\DUtablewidth}{\linewidth}
+\begin{longtable*}[c]{|p{0.226\DUtablewidth}|p{0.110\DUtablewidth}|p{0.435\DUtablewidth}|}
+\hline
+
+variable
+ & 
+type
+ & 
+default
+ \\
+\hline
+
+cache-dir
+ & 
+s
+ & 
+\texttt{\textquotedbl{}fonts\textquotedbl{}}
+ \\
+\hline
+
+names-dir
+ & 
+s
+ & 
+\texttt{\textquotedbl{}names\textquotedbl{}}
+ \\
+\hline
+
+index-file
+ & 
+s
+ & 
+\texttt{\textquotedbl{}luaotfload-names.lua\textquotedbl{}}
+ \\
+\hline
+
+lookups-file
+ & 
+s
+ & 
+\texttt{\textquotedbl{}luaotfload-lookup-cache.lua\textquotedbl{}}
+ \\
+\hline
+\end{longtable*}
+
+The paths \texttt{cache-dir} and \texttt{names-dir} determine the subdirectory
+inside the Luaotfload subtree of the \texttt{luatex-cache} directory where
+the font cache and the font index will be stored, respectively.
+
+Inside the index directory, the names of the index file and the font
+lookup cache will be derived from the respective values of
+\texttt{index-file} and \texttt{lookups-file}. This is the filename base for the
+bytecode compiled version as well as -- for the index -- the gzipped
+version.
+
+
+\subsection{Section \texttt{run}%
+  \label{section-run}%
+}
+
+\setlength{\DUtablewidth}{\linewidth}
+\begin{longtable*}[c]{|p{0.226\DUtablewidth}|p{0.110\DUtablewidth}|p{0.365\DUtablewidth}|}
+\hline
+
+variable
+ & 
+type
+ & 
+default
+ \\
+\hline
+
+anon-sequence
+ & 
+s
+ & 
+\texttt{\textquotedbl{}tex,path,name\textquotedbl{}}
+ \\
+\hline
+
+color-callback
+ & 
+s
+ & 
+\texttt{\textquotedbl{}post\_linebreak\_filter\textquotedbl{}}
+ \\
+\hline
+
+definer
+ & 
+s
+ & 
+\texttt{\textquotedbl{}patch\textquotedbl{}}
+ \\
+\hline
+
+log-level
+ & 
+n
+ & 
+\texttt{0}
+ \\
+\hline
+
+resolver
+ & 
+s
+ & 
+\texttt{\textquotedbl{}cached\textquotedbl{}}
+ \\
+\hline
+
+fontloader
+ & 
+s
+ & 
+\texttt{\textquotedbl{}default\textquotedbl{}}
+ \\
+\hline
+\end{longtable*}
+
+Unqualified font lookups are treated with the flexible “anonymous”
+mechanism. This involves a chain of lookups applied successively until
+the first one yields a match. By default, the lookup will first search
+for TFM fonts using the Kpathsea library. If this wasn’t successful, an
+attempt is made at interpreting the request as an absolute path (like
+the \texttt{{[}/path/to/font/foo.ttf{]}} syntax) or a file name
+(\texttt{file:foo.ttf}). Finally, the request is interpreted as a font name
+and retrieved from the index (\texttt{name:Foo Regular}). This behavior can
+be configured by specifying a list as the value to \texttt{anon-sequence}.
+Available items are \texttt{tex}, \texttt{path}, \texttt{name} -- representing the
+lookups described above, respectively --, and \texttt{file} for searching a
+filename but not an absolute path. Also, \texttt{my} lookups are valid
+values but they should only be used from within TeX documents, because
+there is no means of customizing a \texttt{my} lookups on the command line.
+
+The \texttt{color-callback} option determines the stage at which fonts that
+defined with a \texttt{color=xxyyzz} feature will be colorized. By default
+this happens in a \texttt{post\_linebreak\_filter} but alternatively the
+\texttt{pre\_linebreak\_filter} or \texttt{pre\_output\_filter} may be chosen, which
+is faster but might produce inconsistent output. The
+\texttt{pre\_output\_filter} used to be the default in the 1.x series of
+Luaotfload, whilst later versions up to and including 2.5 hooked into
+the \texttt{pre\_linebreak\_filter} which naturally didn’t affect any glyphs
+inserting during hyphenation. Both are kept around as options to
+restore the previous behavior if necessary.
+
+The \texttt{definer} allows for switching the \texttt{define\_font} callback.
+Apart from the default \texttt{patch} one may also choose the \texttt{generic}
+one that comes with the vanilla fontloader. Beware that this might
+break tools like Fontspec that rely on the \texttt{patch\_font} callback
+provided by Luaotfload to perform important corrections on font data.
+
+The fontloader backend can be selected by setting the value of
+\texttt{fontloader}. The most important choices are \texttt{default}, which will
+load the dedicated Luaotfload fontloader, and \texttt{reference}, the
+upstream package as shipped with Luaotfload. Other than those, a file
+name accessible via kpathsea can be specified.
+
+Alternatively, the individual files that constitute the fontloader can
+be loaded directly. While less efficient, this greatly aids debugging
+since error messages will reference the actual line numbers of the
+source files and explanatory comments are not stripped. Currently,
+three distinct loading strategies are available: \texttt{unpackaged} will
+load the batch that is part of Luaotfload. These contain the identical
+source code that the reference fontloader has been compiled from.
+Another option, \texttt{context} will attempt to load the same files by
+their names in the Context format from the search path. Consequently
+this option allows to use the version of Context that comes with the
+TeX distribution. Distros tend to prefer the stable version (“current”
+in Context jargon) of those files so certain bugs encountered in the
+more bleeding edge Luaotfload can be avoided this way. A third option
+is to use \texttt{context} with a colon to specify a directory prefix where
+the \emph{TEXMF} is located that the files should be loaded from, e. g.
+\texttt{context:\textasciitilde{}/context/tex/texmf-context}. This can be used when
+referencing another distribution like the Context minimals that is
+installed under a different path not indexed by kpathsea.
+
+The value of \texttt{log-level} sets the default verbosity of messages
+printed by Luaotfload. Only messages defined with a verbosity of less
+than or equal to the supplied value will be output on the terminal.
+At a log level of five Luaotfload can be very noisy. Also, printing too
+many messages will slow down the interpreter due to line buffering
+being disabled (see \textbf{setbuf}(3)).
+
+The \texttt{resolver} setting allows choosing the font name resolution
+function: With the default value \texttt{cached} Luaotfload saves the result
+of a successful font name request to a cache file to speed up
+subsequent lookups. The alternative, \texttt{normal} circumvents the cache
+and resolves every request individually. (Since to the restructuring of
+the font name index in Luaotfload 2.4 the performance difference
+between the cached and uncached lookups should be marginal.)
+
+
+\section{FILES%
+  \label{files}%
+}
+
+Luaotfload only processes the first configuration file it encounters at
+one of the search locations. The file name may be either
+\texttt{luaotfload.conf} or \texttt{luaotfloadrc}, except for the dotfile in the
+user’s home directory which is expected at \texttt{\textasciitilde{}/.luaotfloadrc}.
+
+Configuration files are located following a series of steps. The search
+terminates as soon as a suitable file is encountered. The sequence of
+locations that Luaotfload looks at is
+
+\begin{enumerate}
+\renewcommand{\labelenumi}{\roman{enumi}.}
+\item The current working directory of the LuaTeX process.
+
+\item The subdirectory \texttt{luaotfload/} inside the XDG configuration
+tree, e. g. \texttt{/home/oenothea/config/luaotfload/}.
+
+\item The dotfile.
+
+\item The \emph{TEXMF} (using kpathsea).
+\end{enumerate}
+
+
+\section{SEE ALSO%
+  \label{see-also}%
+}
+
+\textbf{luaotfload-tool}(1), \textbf{luatex}(1), \textbf{lua}(1)
+
+\begin{itemize}
+\item \texttt{texdoc luaotfload} to display the PDF manual for the \emph{Luaotfload}
+package
+
+\item Luaotfload development \url{https://github.com/u-fischer/luaotfload}
+
+\item LuaLaTeX mailing list  \url{http://tug.org/pipermail/lualatex-dev/}
+
+\item LuaTeX                 \url{http://luatex.org/}
+
+\item Luaotfload on CTAN     \url{http://ctan.org/pkg/luaotfload}
+\end{itemize}
+
+
+\section{REFERENCES%
+  \label{references}%
+}
+
+\begin{itemize}
+\item The XDG base specification
+\url{http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html}.
+\end{itemize}
+
+
+\section{AUTHORS%
+  \label{authors}%
+}
+
+\emph{Luaotfload} was developed by the LuaLaTeX dev team
+(\url{https://github.com/lualatex/}). It is currently maintained by Ulrike Fischer
+and Marcel Krüger at \url{https://github.com/u-fischer/luaotfload}
+
+This manual page was written by Philipp Gesang <\href{mailto:phg at phi-gamma.net}{phg at phi-gamma.net}>.
+
+\end{document}


Property changes on: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-conf.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.pdf	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.pdf	2018-09-26 20:50:34 UTC (rev 48771)

Property changes on: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.tex	2018-09-26 20:50:34 UTC (rev 48771)
@@ -0,0 +1,520 @@
+% !Mode:: "TeX:EN:UTF-8:Main"
+\suppresslongerror1%% sigh ...
+%% Copyright (C) 2009-2018
+%%
+%%      by  Elie Roux      <elie.roux at telecom-bretagne.eu>
+%%      and Khaled Hosny   <khaledhosny at eglug.org>
+%%      and Philipp Gesang <phg at phi-gamma.net>
+%%
+%% This file is part of Luaotfload.
+%%
+%%      Home:      https://github.com/lualatex/luaotfload
+%%      Support:   <lualatex-dev at tug.org>.
+%%
+%% Luaotfload is under the GPL v2.0 (exactly) license.
+%%
+%% ----------------------------------------------------------------------------
+%%
+%% Luaotfload is free software; you can redistribute it and/or
+%% modify it under the terms of the GNU General Public License
+%% as published by the Free Software Foundation; version 2
+%% of the License.
+%%
+%% Luaotfload is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with Luaotfload; if not, see <http://www.gnu.org/licenses/>.
+%%
+%% ----------------------------------------------------------------------------
+%%
+
+\documentclass{ltxdoc}
+
+\makeatletter
+
+\usepackage {metalogo,multicol,fancyvrb,xspace}
+\usepackage [x11names] {xcolor}
+
+\def \primarycolor   {DodgerBlue4} %%-> rgb  16  78 139 | #104e8b
+\def \secondarycolor {Goldenrod4}  %%-> rgb 139 105 200 | #8b6914
+
+\usepackage[
+    bookmarks=true,
+   colorlinks=true,
+    linkcolor=\primarycolor,
+     urlcolor=\secondarycolor,
+    citecolor=\primarycolor,
+     pdftitle={The Luaotfload package},
+   pdfsubject={OpenType layout system for Plain TeX and LaTeX},
+    pdfauthor={Elie Roux & Khaled Hosny & Philipp Gesang & Ulrike Fischer},
+  pdfkeywords={luatex, lualatex, unicode, opentype}
+]{hyperref}
+
+\usepackage {fontspec}
+\usepackage {unicode-math}
+
+\setmainfont[
+% Numbers     = OldStyle, %% buggy with font cache
+  Ligatures   = TeX,
+  BoldFont    = {Linux Libertine O Bold},
+  ItalicFont  = {Linux Libertine O Italic},
+  SlantedFont = {Linux Libertine O Italic},
+]{Linux Libertine O}
+\setmonofont[Ligatures=TeX,Scale=MatchLowercase]{InconsolataN-Regular.otf}
+%setsansfont[Ligatures=TeX]{Linux Biolinum O}
+\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{Iwona Medium}
+%setmathfont{XITS Math}
+
+\usepackage{hologo}
+
+\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\LUALATEX {Lua\LaTeX\xspace}
+\newcommand\CONTEXT  {Con\TeX t\xspace}
+\newcommand\OpenType {\identifier{Open\kern-.25ex Type}\xspace}
+
+%% \groupedcommand, with some omissions taken from syst-aux.mkiv
+\let \handlegroupnormalbefore \relax
+\let \handlegroupnormalafter  \relax
+
+\protected \def \handlegroupnormal #1#2{%
+  \bgroup % 1
+  \def \handlegroupbefore {#1}%
+  \def \handlegroupafter  {#2}%
+  \afterassignment \handlegroupnormalbefore
+  \let \next =
+}
+
+\def \handlegroupnormalbefore {%
+  \bgroup % 2
+  \handlegroupbefore
+  \bgroup % 3
+  \aftergroup \handlegroupnormalafter%
+}
+
+\def \handlegroupnormalafter {%
+  \handlegroupafter
+  \egroup % 3
+  \egroup % 2
+}
+
+\let \groupedcommand \handlegroupnormal %% only the two arg version
+
+\def \definehighlight [#1][#2]{%
+  \ifcsname #1\endcsname\else
+    \expandafter\def\csname #1\endcsname{%
+      \leavevmode
+      \groupedcommand {#2}\empty%
+    }
+  \fi%
+}
+
+%% old, simplistic definition: obsolete now that we have
+%% \groupedcommand
+%\def\definehighlight[#1][#2]%
+ %{\ifcsname #1\endcsname\else
+    %\expandafter\def\csname #1\endcsname%
+      %{\bgroup#2\csname #1_indeed\endcsname}
+    %\expandafter\def\csname #1_indeed\endcsname##1%
+      %{##1\egroup}%
+  %\fi}
+
+\def\restoreunderscore{\catcode`\_=12\relax}
+
+\definehighlight         [fileent][\ttfamily\restoreunderscore]         %% files, dirs
+\definehighlight        [texmacro][\sffamily\itshape\textbackslash]     %% cs
+\definehighlight        [luaident][\sffamily\itshape\restoreunderscore] %% lua identifiers
+\definehighlight      [identifier][\sffamily]                           %% names
+\definehighlight          [abbrev][\rmfamily\scshape]                   %% acronyms
+\definehighlight        [emphasis][\rmfamily\slshape]                   %% level 1 emph
+
+\definehighlight       [Largefont][\Large]                              %% font size
+\definehighlight       [smallcaps][\sc]                                 %% font feature
+\definehighlight [nonproportional][\tt]                                 %% font switch
+
+\newcommand*\email[1]{\href{mailto:#1}{#1}}
+
+\renewcommand\partname{Part}%% gets rid of the stupid “file” heading
+
+\usepackage{syntax}%% bnf for font request syntax
+
+\usepackage{titlesec}
+
+\def\movecountertomargin#1{\llap{\rmfamily\upshape#1\hskip2em}}
+\def\zeropoint{0pt}
+\titleformat \part
+             {\normalsize\rmfamily\bfseries}
+             {\movecountertomargin\thepart} \zeropoint {}
+\titleformat \section
+             {\normalsize\rmfamily\scshape}
+             {\movecountertomargin\thesection} \zeropoint {}
+\titleformat \subsection
+             {\small\rmfamily\itshape}
+             {\movecountertomargin\thesubsection} \zeropoint {}
+\titleformat \subsubsection
+             {\normalsize\rmfamily\upshape}
+             {\movecountertomargin\thesubsubsection} \zeropoint {}
+
+\usepackage{tocloft}
+\renewcommand \cftpartfont   {\rmfamily\upshape}
+\renewcommand \cftsecfont    {\rmfamily\upshape}
+\renewcommand \cftsubsecfont {\rmfamily\upshape}
+\setlength \cftbeforepartskip {1ex}
+\setlength \cftbeforesecskip  {1ex}
+
+\VerbatimFootnotes
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% structurals
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def \definestructural #1{%
+  \expandafter \let \csname end#1\endcsname \relax
+
+  \expandafter \def \csname begin#1\endcsname {%
+    \@ifnextchar[{\csname begin#1indeed\endcsname}
+                 {\csname begin#1indeed\endcsname[]}%
+  }
+
+  \expandafter \def \csname begin#1indeed\endcsname [##1]##2{%
+    \edef \first {##1}%
+    \ifx \first \empty
+      \csname #1\endcsname [##2]{##2}%
+    \else
+      \csname #1\endcsname [\first]{##2}%
+    \fi
+  }
+}
+
+\definestructural {section}
+\definestructural {subsection}
+\definestructural {subsubsection}
+
+\def \fakesection #1{\section*{#1}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% inline verbatim
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Context offers both \type{…} and \type<<…>>, but not an unbalanced
+%% one that we could map directly onto Latex’s \verb|…|.
+\usepackage{pdfpages}
+\usepackage {listings}
+\usepackage {luatexbase}
+\lstset {
+  basicstyle=\ttfamily,
+}
+
+%\let \inlinecode \lstinline
+\protected \def \inlinecode {\lstinline}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% codelistings; this sucks hard since we lack access to buffers
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newcount \othercatcode  \othercatcode 12
+\newcount \activecatcode \othercatcode 13
+
+\newcatcodetable \vrbcatcodes
+\setcatcodetable \vrbcatcodes {%
+  \catcodetable \CatcodeTableIniTeX
+  \catcode  9 \othercatcode %% \tabasciicode
+  \catcode 13 \othercatcode %% \endoflineasciicode
+  \catcode 12 \othercatcode %% \formfeedasciicode
+  \catcode 26 \othercatcode %% \endoffileasciicode
+  \catcode 32 \othercatcode %% \spaceasciicode
+}
+
+\directlua {
+  document = document or { }
+  document.vrbcatcodesidx = tonumber (\the \vrbcatcodes)
+}
+
+\newcatcodetable \literalcatcodes
+\setcatcodetable \literalcatcodes {%
+  \catcodetable \CatcodeTableString
+  \catcode 32 \activecatcode %% \spaceasciicode
+}
+
+\def \listingsurroundskip {\vskip \baselineskip}
+
+\def \beginlisting {%
+  \noindent
+  \begingroup
+    \catcodetable \vrbcatcodes
+    \beginlistingindeed%
+}
+
+\directlua {
+  local texsprint       = tex.sprint
+  local stringis_empty  = string.is_empty
+  local stringsub       = string.sub
+  local stringgsub      = string.gsub
+  %local backslash       = unicode.utf8.char (0x200c)
+  local backslash       = unicode.utf8.char (0x5c)
+  local escaped         = [[\string\string\string\]]
+  document.printlines = function (buffer)
+    local lines = string.explode (buffer, "\noexpand\n")
+    print ""
+    for i, line in next, lines do
+      local line = stringgsub (line, backslash, escaped)
+      if stringis_empty (line) then
+        print (i, "listing: <empty line />")
+        texsprint [[\string\listingpar]]
+      else
+        local line = [[\string\beginlistingline]]
+                  .. line
+                  .. [[\string\endlistingline]]
+                  .. [[\string\listingpar]]
+        print (i, "listing: «" .. line .. "»")
+        texsprint (document.vrbcatcodesidx, line)
+      end
+    end
+  end
+}
+
+\def \listingpar {\endgraf}
+
+\let \endlistingline \relax
+\let \endlisting     \relax
+
+\protected \def \beginlistingline{%
+  \leavevmode
+  \begingroup
+    \beginlistinglineindeed%
+}
+
+\def \beginlistinglineindeed #1\endlistingline{%
+  \endgroup
+  \hbox{%
+    \addfontfeature {RawFeature=-tlig;-liga}%% So one can’t just turn them all off at once using the ``Ligatures`` key?
+    \obeyspaces
+    #1}%
+}
+
+\def \beginlistingindeed#1\endlisting{%
+  \endgroup
+  \begingroup
+    \endgraf
+    \listingsurroundskip
+    \ttfamily
+    \small
+    \parindent = 0em
+    \leftskip = 2em
+    \hangindent = 2em
+    \directlua{document.printlines ([==[\detokenize {#1}]==])}%
+    \listingsurroundskip
+  \endgroup
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% enumerations and lists
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def \definelist [#1]#2{% name, itemcode
+  \expandafter \def \csname begin#1\endcsname {%
+    \begin {itemize}
+      \let \normalitem = \item
+      \def \altitem ####1{%
+        \def \first {####1}%
+        #2
+      }
+      \let \beginnormalitem \item
+      \let \endnormalitem   \relax
+      \let \beginaltitem    \altitem
+      \let \endaltitem      \relax
+  }
+
+  \expandafter \def \csname end#1\endcsname {%
+    \end {itemize}
+  }
+}
+
+\definelist  [descriptions]{\normalitem {\textbf \first}\hfill\break}
+\definelist   [definitions]{\normalitem {\fileent {\first}}}
+\definelist      [filelist]{\normalitem {\fileent {\first}}\space--\hskip 1em}
+\definelist  [functionlist]{\normalitem {\luaident {\first}}\hfill\break}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% columns
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def \begindoublecolumns {\begin {multicols} {2}}
+\def \enddoublecolumns   {\end {multicols}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% alignment
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def \begincentered {\begin {center}}
+\def \endcentered   {\end {center}}
+
+\def \beginnarrower {\begin {quote}}
+\def \endnarrower   {\end {quote}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% special elements
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\let \beginfrontmatter \relax
+\let \endfrontmatter   \relax
+
+\def \beginabstractcontent {\begin {abstract}}
+\def \endabstractcontent   {\end {abstract}}
+
+\let \setdocumenttitle      \title
+\let \setdocumentdate       \date
+\let \setdocumentauthor     \author
+\let \typesetdocumenttitle  \maketitle
+
+\AtBeginDocument {%% seriously?
+  \let \typesetcontent \tableofcontents%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% floats
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% syntax definition
+\def \beginsyntaxfloat #1#2{%% #1:label #2:caption
+  \begin {figure} [b]
+    \edef \syntaxlabel  {#1}%
+    \def \syntaxcaption {#2}%
+    \setlength\grammarparsep{0pt plus 2pt minus 2pt}%
+    \setlength\grammarindent{5cm}%
+    \begingroup
+      \small
+      \begin {grammar}
+}
+
+\def \endsyntaxfloat {%
+      \end {grammar}
+    \endgroup
+    \caption \syntaxcaption
+    \label   \syntaxlabel
+  \end {figure}
+}
+
+%% figures, e.g. the file graph
+\def \figurefloat #1#2#3{%% #1:label #2:caption #3:file
+  \begin {figure} [b]
+    \caption {#2}%
+    \includegraphics[width=\textwidth]{#3}%
+    \label {#1}
+  \end {figure}
+}
+
+%% tables
+\def \tablefloat #1#2{%% #1:label #2:caption
+  \begin {table} [t]
+    \hrule
+    \caption {#2}%
+    \label {#1}
+    \hrule
+  \end {table}
+}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% hyperlinks
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\protected \def \hyperlink{%
+  \@ifnextchar[{\hyperlinkindeed}%
+               {\hyperlinkindeed[]}%
+}
+
+\def \hyperlinkindeed [#1]#2{%
+  \def \first {#1}%
+  \ifx \first \empty
+    \url {#2}%
+  \else
+    \href {#2}{#1}%
+  \fi%
+}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% tables
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Our tables aren’t anything special so we stick with “tabular” on the
+%% Latex end.
+%%
+%% This is going to be largely incompatible with Context since format
+%% specifications work quite differently (even between different
+%% Context table variants).
+
+\def \begintabulate [#1]#2\endtabulate{%
+  \begingroup
+    \let \beginrow  = \relax %% -> \NC in Context
+    \let \newcell   = &      %% -> \NC
+    \let \endrow    = \cr    %% -> \NC \NR
+    \begin {tabular}{#1}%
+      #2
+    \end {tabular}
+  \endgroup
+}
+
+\let \endtabulate \relax
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% escaped characters
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\let \charpercent   \textpercent
+\let \charbackslash \textbackslash
+\let \chartilde     \textasciitilde
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% main
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\makeatother
+
+\newif \ifcontextmkiv \contextmkivfalse
+
+\usepackage{luacode}
+
+% a few lua functions to grab the file lists.
+\begin{luacode}
+require("luaotfload-filelist.lua")
+
+function printctxlibslist ()
+  t= luaotfload.filelist.selectctxlibsentries (luaotfload.filelist.data)
+ for i,v in ipairs (t) do
+  tex.sprint("\\beginaltitem {"..v.name.. v.ext.."}\\endaltitem")
+ end
+end
+
+function printctxallgenericlist ()
+  t= luaotfload.filelist.selectctxgeneentries (luaotfload.filelist.data)
+ for i,v in ipairs (t) do
+  tex.sprint("\\beginaltitem {"..v.ctxpref..v.name..v.ext.."}\\endaltitem")
+ end
+end
+
+function printctxfontlist ()
+  t= luaotfload.filelist.selectctxfontentries (luaotfload.filelist.data)
+ for i,v in ipairs (t) do
+  tex.sprint("\\beginaltitem {"..v.name..v.ext.."}\\endaltitem")
+ end
+end
+\end{luacode}
+
+
+\begin {document}
+  \input {luaotfload-main.tex}
+\clearpage
+\includepdf[fitpaper,pagecommand={\label{file-graph}}]{filegraph}
+\includepdf[pages=-]{luaotfload-conf.pdf}
+\includepdf[pages=-]{luaotfload-tool.pdf}
+\end {document}
+
+


Property changes on: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-latex.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex	2018-09-26 20:50:34 UTC (rev 48771)
@@ -0,0 +1,1899 @@
+%% Copyright (C) 2009-2018
+%%
+%%      by  Elie Roux      <elie.roux at telecom-bretagne.eu>
+%%      and Khaled Hosny   <khaledhosny at eglug.org>
+%%      and Philipp Gesang <phg at phi-gamma.net>
+%%
+%% This file is part of Luaotfload.
+%%
+%%      Home:      https://github.com/lualatex/luaotfload
+%%      Support:   <lualatex-dev at tug.org>.
+%%
+%% Luaotfload is under the GPL v2.0 (exactly) license.
+%%
+%% ----------------------------------------------------------------------------
+%%
+%% Luaotfload is free software; you can redistribute it and/or
+%% modify it under the terms of the GNU General Public License
+%% as published by the Free Software Foundation; version 2
+%% of the License.
+%%
+%% Luaotfload is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with Luaotfload; if not, see <http://www.gnu.org/licenses/>.
+%%
+%% ----------------------------------------------------------------------------
+%%
+
+\beginfrontmatter
+
+  \setdocumenttitle  {The \identifier{luaotfload} package}
+  \setdocumentdate   {2018/09/24 v2.9}
+  \setdocumentauthor {Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer\\
+                      Home:    \hyperlink {https://github.com/lualatex/luaotfload}\\
+                      New Home: \hyperlink {https://github.com/u-fischer/luaotfload}\\
+                      Support: \email     {lualatex-dev at tug.org}}
+
+  \typesetdocumenttitle
+
+  \beginabstractcontent
+    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.
+
+    After discussion of the font loading API, this manual gives an
+    overview of the core components of \identifier{Luaotfload}: The
+    packaged font loader code, the names database, configuration, and
+    helper functions on the \LUA\ end.
+  \endabstractcontent
+
+\endfrontmatter
+
+\typesetcontent
+
+\beginsection {New in version 2.9 (by Ulrike Fischer)}
+
+On the one side there is not very much new in this version: The native components of \identifier{Luaotfload} are nearly unchanged. A few bugs have been corrected, the various files lists which loads the components of the font loader have been cleaned up.
+
+On the other side there is a lot new:
+
+\begindescriptions
+
+  \beginaltitem {Fontloader} The fontloader files imported from \CONTEXT\ have been updated to the current version.
+   This was necessary to make \identifier{Luaotfload} compatible with the comimg \LUATEX 1.08. Compared to the previous version from february 2017 quite a number of things have changed. Most importantly the handling of arabic fonts has greatly improved. But this also means that changes in the output are possible.
+  \endaltitem
+
+  \beginaltitem {Lualibs} The update of the fontloader files also required an update of the \identifier{Lualibs} package. This \identifier{Luaotfload} versions needs version 2.6 of \identifier{Lualibs}.
+  \endaltitem
+
+  \beginaltitem {Maintenance} As the current maintainer wasn't available and it was urgent to get a \identifier{Luaotfload} compatible with \LUATEX 1.08 maintenance has been transfered to Ulrike Fischer and Marcel Krüger. The package is currently maintained and developed at \hyperlink{https://github.com/u-fischer/luaotfload.git}. Issues should be reported there.
+  \endaltitem
+
+  \beginaltitem {Documentation}
+  The core of documentation is nearly unchanged. I added this introduction. I recreated with the help of @marmot the graphic. I updated the file lists. I imported as appendix pdf versions of the two man files which are part of the \identifier{Luaotfload} documentation.
+  \endaltitem
+
+\enddescriptions
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {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 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 \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{%
+  Unfortunately, \identifier{luaotfload} doesn‘t support many Indic
+  scripts right now.
+  Assistance in implementing the prerequisites is greatly
+  appreciated.
+}
+scripts.
+
+\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.
+
+However, until recently the only way to use them directly in the \TEX
+world was with the \XETEX engine.
+
+Unlike \XETEX, \LUATEX has no built-in support for \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.
+
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Thanks}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\identifier{Luaotfload} is part of \LUALATEX, the community-driven
+project to provide a foundation for using the \LATEX format with the
+full capabilites of the \LUATEX engine.
+%
+As such, the distinction between end users, contributors, and project
+maintainers is intentionally kept less strict, lest we unduly
+personalize the common effort.
+
+Nevertheless, the current maintainers would like to express their
+gratitude to Khaled Hosny, Akira Kakuto, Hironori Kitagawa and Dohyun
+Kim.
+%
+Their contributions -- be it patches, advice, or systematic
+testing -- made the switch from version 1.x to 2.2 possible.
+%
+Also, Hans Hagen, the author of the font loader, made porting the
+code to \LATEX a breeze due to the extra effort he invested into
+isolating it from the rest of \CONTEXT, not to mention his assistance
+in the task and willingness to respond to our suggestions.
+
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Loading Fonts}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\identifier{luaotfload} supports an extended font request syntax:
+
+\beginnarrower
+      \nonproportional{\string\font\string\foo\space= \string{}%
+      \meta{prefix}\nonproportional{:}%
+      \meta{font name}\nonproportional{:}%
+      \meta{font features}\nonproportional{\string}}%
+      \meta{\TEX font features}
+\endnarrower
+
+\noindent
+The curly brackets are optional and escape the spaces in the enclosed
+font name.
+%
+Alternatively, double quotes serve the same purpose.
+%
+A selection of individual parts of the syntax are discussed below;
+for a more formal description see figure \ref{font-syntax}.
+
+\beginsyntaxfloat
+  {font-syntax}
+  {Font request syntax.
+   Braces or double quotes around the
+   \emphasis{specification} rule will
+   preserve whitespace in file names.
+   In addition to the font style modifiers
+   (\emphasis{slash-notation}) given above, there
+   are others that are recognized but will be silently
+   ignored: \nonproportional{aat},
+            \nonproportional{icu}, and
+            \nonproportional{gr}.
+   The special terminals are:
+   \smallcaps {feature\textunderscore id} for a valid font
+      feature name and
+   \smallcaps {feature\textunderscore value} for the corresponding
+      value.
+   \smallcaps {tfmname} is the name of a \abbrev{tfm} file.
+   \smallcaps {digit}  again refers to bytes 48--57, and
+   \smallcaps {all\textunderscore characters} to all byte values.
+   \smallcaps {csname} and \smallcaps {dimension} are the \TEX concepts.}
+%
+      <definition>      ::= `\\font', {\sc csname}, `=', <font request>, [ <size> ] ;
+
+      <size>            ::= `at', {\sc dimension} ;
+
+      <font request>    ::= `"', <unquoted font request> `"'
+      \alt                  `{', <unquoted font request> `}'
+      \alt                  <unquoted font request> ;
+
+      <unquoted font request> ::= <specification>, [`:', <feature list> ]
+      \alt                        <path lookup>, [ [`:'], <feature list> ] ;
+
+      <specification>    ::= <prefixed spec>, [ <subfont no> ], \{ <modifier> \}
+      \alt                   <anon lookup>, \{ <modifier> \} ;
+
+      <prefixed spec>    ::= `combo:', <combo list>
+      \alt                   `file:', <file lookup>
+      \alt                   `name:', <name lookup> ;
+
+      <combo list>       ::= <combo def 1>, \{ `;', <combo def>  \} ;
+
+      <combo def 1>      ::= <combo id>, `->', <combo id> ;
+
+      <combo def>        ::= <combo id>, `->', <combo id chars> ;
+
+      <combo id>         ::= (`(', \{ {\sc digit} \}, `)' | \{ {\sc digit} \} ) ;
+
+      <combo id chars>   ::= (`(', \{ {\sc digit} \}, `,', <combo chars>, `)'
+      \alt                   \{ {\sc digit} \} ) ;
+
+      <combo chars>      ::= `fallback'
+      \alt                   \{ <combo range>, \{ `*', <combo range> \} \} ;
+
+      <combo range>      ::= <combo num>, [ `-', <combo num> ] ;
+
+      <combo num>        ::= `0x', \{ {\sc hexdigit}  \}
+      \alt                   `U+', \{ {\sc digit} \}
+      \alt                   \{ {\sc digit} \} ;
+
+      <file lookup>      ::= \{ <name character> \} ;
+
+      <name lookup>      ::= \{ <name character> \} ;
+
+      <anon lookup>      ::= {\sc tfmname} | <name lookup> ;
+
+      <path lookup>      ::= `[', \{ <path content> \}, `]', [ <subfont no> ] ;
+
+      <path content>     ::= <path balanced>
+      \alt                   `\\', {\sc all_characters}
+      \alt                   {\sc all_characters} - `]'
+
+      <path balanced>    ::= `[', [ <path content> ], `]'
+
+      <modifier>         ::= `/', (`I' | `B' | `BI' | `IB' | `S=', \{ {\sc digit} \} ) ;
+
+      <subfont no>       ::= `(', \{ {\sc digit} \}, `)' ;
+
+      <feature list>     ::= <feature expr>, \{ `;', <feature expr> \} ;
+
+      <feature expr>     ::= {\sc feature_id}, `=', {\sc feature_value}
+      \alt                   <feature switch>, {\sc feature_id} ;
+
+      <feature switch>   ::= `+' | `-' ;
+
+      <name character>   ::= {\sc all_characters} - ( `(' | `/' | `:' ) ;
+\endsyntaxfloat
+
+%% Below guarded space gets borked in index; why‽
+\beginsubsection{Prefix -- the \identifier{luaotfload}{ }Way}
+
+In \identifier{luaotfload}, the canonical syntax for font requests
+requires a \emphasis{prefix}:
+%
+\beginnarrower
+  \nonproportional{\string\font\string\fontname\space= }%
+  \meta{prefix}%
+  \nonproportional{:}%
+  \meta{fontname}%
+  \dots
+\endnarrower
+%
+where \meta{prefix} is either \inlinecode{file:} or \inlinecode {name:}.\footnote{%
+  \identifier{Luaotfload} also knows two further prefixes, \inlinecode {kpse:}
+  and \inlinecode {my:}.
+  %
+  A \inlinecode {kpse} lookup is restricted to files that can be found by
+  \identifier{kpathsea} and will not attempt to locate system fonts.
+  %
+  This behavior can be of value when an extra degree of encapsulation is
+  needed, for instance when supplying a customized tex distribution.
+
+  The \inlinecode {my} lookup takes this a step further: it lets you define
+  a custom resolver function and hook it into the \luaident{resolve_font}
+  callback.
+  %
+  This ensures full control over how a file is located.
+  %
+  For a working example see the
+  \hyperlink [test repo]{https://bitbucket.org/phg/lua-la-tex-tests/src/5f6a535d/pln-lookup-callback-1.tex}.
+}
+%
+It determines whether the font loader should interpret the request as
+a \emphasis{file name} or
+  \emphasis{font name}, respectively,
+which again influences how it will attempt to locate the font.
+%
+Examples for font names are
+            “Latin Modern Italic”,
+            “GFS Bodoni Rg”, and
+            “PT Serif Caption”
+-- they are the human readable identifiers
+usually listed in drop-down menus and the like.\footnote{%
+  Font names may appear like a great choice at first because they
+  offer seemingly more intuitive identifiers in comparison to arguably
+  cryptic file names:
+  %
+  “PT Sans Bold” is a lot more descriptive than \fileent{PTS75F.ttf}.
+  On the other hand, font names are quite arbitrary and there is no
+  universal method to determine their meaning.
+  %
+  While \identifier{luaotfload} provides fairly sophisticated heuristic
+  to figure out a matching font style, weight, and optical size, it
+  cannot be relied upon to work satisfactorily for all font files.
+  %
+  For an in-depth analysis of the situation and how broken font names
+  are, please refer to
+  \hyperlink [this post]{http://www.ntg.nl/pipermail/ntg-context/2013/073889.html}
+  by Hans Hagen, the author of the font loader.
+  %
+  If in doubt, use filenames.
+  %
+  \fileent{luaotfload-tool} can perform the matching for you with the
+  option \inlinecode {--find=<name>}, and you can use the file name it returns
+  in your font definition.
+}
+%
+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.
+
+File names are whatever your file system allows them to be, except
+that that they may not contain the characters
+  \inlinecode {(},
+  \inlinecode {:}, and
+  \inlinecode {/}.
+%
+As is obvious from the last exception, the \inlinecode {file:} lookup will
+not process paths to the font location -- only those
+files found when generating the database are addressable this way.
+%
+Continue below in the \XETEX section if you need to load your fonts
+by path.
+%
+The file names corresponding to the example font names above are
+  \fileent{lmroman12-italic.otf},
+  \fileent{GFSBodoni.otf}, and
+  \fileent{PTZ56F.ttf}.
+
+\endsubsection
+
+\beginsubsection {Bracketed Lookups}
+\label{sec:bracket}
+Bracketed lookups allow for arbitrary character content to be used in a
+definition.
+%
+A simple bracketed request looks follows the scheme
+
+\beginnarrower
+  \nonproportional{\string\font\string\fontname\space = [}%
+  \meta{/path/to/file}%
+  \nonproportional{]}
+\endnarrower
+
+\noindent
+Inside the square brackets, every character except for a closing bracket is
+permitted, allowing for  arbitrary paths to a font file -- including Windows
+style paths with UNC or drive letter prepended -- to be specified.
+%
+The \identifier{Luaotfload} syntax differs from \XETEX in that the subfont
+selector goes \emphasis{after} the closing bracket:
+
+\beginnarrower
+  \nonproportional{\string\font\string\fontname\space = [}%
+  \meta{/path/to/file}%
+  \nonproportional{]}
+  \nonproportional{(}n\nonproportional{)}
+\endnarrower
+
+Naturally, path-less file names are equally valid and processed the
+same way as an ordinary \inlinecode {file:} lookup.
+
+\beginsubsection {Compatibility}
+
+In addition to the regular prefixed requests, \identifier{luaotfload}
+accepts loading fonts the \XETEX way.
+%
+There are again two modes: bracketed and unbracketed.
+For the bracketed variety, see above, \ref{sec:bracket}.
+
+Unbracketed (or, for lack of a better word: \emphasis{anonymous})
+font requests resemble the conventional \TEX syntax.
+
+\beginnarrower
+  \nonproportional{\string\font\string\fontname\space= }%
+  \meta{font name}
+  \dots
+\endnarrower
+\endsubsection
+
+However, they have a broader spectrum of possible interpretations:
+before anything else, \identifier{luaotfload} attempts to load a
+traditional \TEX Font Metric (\abbrev{tfm} or \abbrev{ofm}).
+%
+If this fails, it performs a \inlinecode {path:} lookup, which itself will
+fall back to a \inlinecode {file:} lookup.
+%
+Lastly, if none of the above succeeded, attempt to resolve the request as a
+\inlinecode {name:} lookup by searching the font index for \meta{font name}.
+%
+The behavior of this “anonymous” lookup is configurable, see the configuation
+manpage for details.
+
+Furthermore, \identifier{luaotfload} supports the slashed (shorthand)
+font style notation from \XETEX.
+
+\beginnarrower
+  \nonproportional{\string\font\string\fontname\space= }%
+  \meta{font name}%
+  \nonproportional{/}%
+  \meta{modifier}
+  \dots
+\endnarrower
+
+\noindent
+Currently, four style modifiers are supported:
+  \inlinecode {I} for italic shape,
+  \inlinecode {B} for bold   weight,
+  \inlinecode {BI} or \inlinecode {IB} for the combination of both.
+%
+Other “slashed” modifiers are too specific to the \XETEX engine and
+have no meaning in \LUATEX.
+
+\endsubsection
+
+\beginsubsection{Examples}
+
+\beginsubsubsection{Loading by File Name}
+
+For example, conventional \TeX\ font can be loaded with a
+\inlinecode {file:} request like so:
+
+\beginlisting
+  \font \lmromanten = {file:ec-lmr10} at 10pt
+\endlisting
+
+The \OpenType version of Janusz Nowacki’s font \emphasis{Antykwa
+Półtawskiego}\footnote{%
+  \hyperlink {http://jmn.pl/antykwa-poltawskiego/}, also available in
+  in \TEX Live.
+}
+in its condensed variant can be loaded as follows:
+
+\beginlisting
+  \font \apcregular = file:antpoltltcond-regular.otf at 42pt
+\endlisting
+
+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:
+
+\beginlisting
+  \font \gfsporson = "[/tmp/GFSPorson.otf]" at 12pt
+\endlisting
+
+\identifier{TrueType} collection files (the extension is usually
+\inlinecode{.ttc}) contain more than a single font. In order to refer to these
+subfonts, the respective index may be added in parentheses after the file
+name.\footnote{%
+  Incidentally, this syntactical detail also prevents one from loading files
+  that end in balanced parentheses.
+}
+
+\beginlisting
+  \font \cambriamain = "file:cambria.ttc(0)" at 10pt
+  \font \cambriamath = "file:cambria.ttc(1)" at 10pt
+\endlisting
+
+and likewise, requesting subfont inside a TTC container by path:
+
+\beginlisting
+  \font \asanamain = "[/home/typesetter/.fonts/math/asana.ttc](0):mode=node;+tlig" at 10pt
+  \font \asanamath = "[/home/typesetter/.fonts/math/asana.ttc](1):mode=base" at 10pt
+\endlisting
+
+\endsubsubsection
+
+\beginsubsubsection{Loading by Font Name}
+
+The \inlinecode {name:} lookup does not depend on cryptic filenames:
+
+\beginlisting
+  \font \pagellaregular = {name:TeX Gyre Pagella} at 9pt
+\endlisting
+
+A bit more specific but essentially the same lookup would be:
+
+\beginlisting
+  \font \pagellaregular = {name:TeX Gyre Pagella Regular} at 9pt
+\endlisting
+
+\noindent
+Which fits nicely with the whole set:
+
+\beginlisting
+  \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}
+
+  ...
+\endlisting
+
+\endsubsubsection
+
+\beginsubsubsection{Modifiers}
+
+If the entire \emphasis{Iwona} family\footnote{%
+  \hyperlink {http://jmn.pl/kurier-i-iwona/},
+  also in \TEX Live.
+}
+is installed in some location accessible by \identifier{luaotfload},
+the regular shape can be loaded as follows:
+
+\beginlisting
+  \font \iwona = Iwona at 20pt
+\endlisting
+
+\noindent
+To load the most common of the other styles, the slash notation can
+be employed as shorthand:
+
+\beginlisting
+  \font \iwonaitalic     = Iwona/I    at 20pt
+  \font \iwonabold       = Iwona/B    at 20pt
+  \font \iwonabolditalic = Iwona/BI   at 20pt
+\endlisting
+
+\noindent
+which is equivalent to these full names:
+
+\beginlisting
+  \font \iwonaitalic     = "Iwona Italic"       at 20pt
+  \font \iwonabold       = "Iwona Bold"         at 20pt
+  \font \iwonabolditalic = "Iwona BoldItalic"   at 20pt
+\endlisting
+
+\endsubsubsection
+\endsubsection
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Font features}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\emphasis{Font features} are the second to last component in the
+general scheme for font requests:
+
+\beginnarrower
+  \nonproportional{\string\font\string\foo\space= "}%
+  \meta{prefix}%
+  \nonproportional{:}%
+  \meta{font name}%
+  \nonproportional{:}%
+  \meta{font features}%
+  \meta{\TEX font features}%
+  \nonproportional{"}
+\endnarrower
+
+\noindent
+If style modifiers are present (\XETEX style), they must precede
+\meta{font features}.
+
+The element \meta{font features} is a semicolon-separated list of feature
+tags\footnote{%
+  Cf. \hyperlink {http://www.microsoft.com/typography/otspec/featurelist.htm}.
+}
+and font options.
+%
+Prepending a font feature with a \inlinecode{+} (plus sign) enables it,
+whereas a \inlinecode{-} (minus) disables it. For instance, the request
+
+\beginlisting
+  \font \test = LatinModernRoman:+clig;-kern
+\endlisting
+
+\noindent activates contextual ligatures (\inlinecode{clig}) and
+disables kerning (\inlinecode{kern}).
+%
+Alternatively the options \inlinecode{true} or \inlinecode{false} can
+be passed to the feature in a key/value expression.
+%
+The following request has the same meaning as the last one:
+
+\beginlisting
+  \font \test = LatinModernRoman:clig=true;kern=false
+\endlisting
+
+\noindent
+Furthermore, this second syntax is required should a font feature
+accept other options besides a true/false switch.
+%
+For example, \emphasis{stylistic alternates} (\inlinecode{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, \inlinecode{random}.
+
+%% TODO   verify that this actually works with a font that supports
+%%        the salt/random feature!\fi
+\beginlisting
+  \font \librmsaltfirst = LatinModernRoman:salt=1
+\endlisting
+
+\beginsubsection {Basic font features}
+
+\begindescriptions
+
+  \beginaltitem {mode}
+         \identifier{luaotfload} has two \OpenType processing
+         \emphasis{modes}:
+         \identifier{base} and \identifier{node}.
+
+         \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 \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.
+
+         By default \identifier{luaotfload} is in \identifier{node}
+         mode, and \identifier{base} mode has to be requested where needed,
+         e.~g. for math fonts.
+  \endaltitem
+
+  \beginaltitem {script} \label{script-tag}
+         An \OpenType script tag;\footnote{%
+           See \hyperlink {http://www.microsoft.com/typography/otspec/scripttags.htm}
+           for a list of valid values.
+           %
+           For scripts derived from the Latin alphabet the value
+           \inlinecode{latn} is good choice.
+         }
+         the default value is \inlinecode{dflt}.
+         %
+         Some fonts, including very popular ones by foundries like Adobe,
+         do not assign features to the \inlinecode{dflt} script, in
+         which case the script needs to be set explicitly.
+  \endaltitem
+
+  \beginaltitem {language}
+         An \OpenType language system identifier,\footnote{%
+           Cf. \hyperlink {http://www.microsoft.com/typography/otspec/languagetags.htm}.
+         }
+         defaulting to \inlinecode{dflt}.
+  \endaltitem
+
+  \beginaltitem {color}
+         A font color, defined as a triplet of two-digit hexadecimal
+         \abbrev{rgb} values, with an optional fourth value for
+         transparency
+         (where \inlinecode{00} is completely transparent and
+         \inlinecode{FF} is opaque).
+
+         For example, in order to set text in semitransparent red:
+
+         \beginlisting
+      \font \test = "Latin Modern Roman:color=FF0000BB"
+         \endlisting
+  \endaltitem
+
+  \beginaltitem {kernfactor \& letterspace}
+         Define a font with letterspacing (tracking) enabled.
+         %
+         In \identifier{luaotfload}, letterspacing is implemented by
+         inserting additional kerning between glyphs.
+
+         This approach is derived from and still quite similar to the
+         \emphasis{character kerning} (\texmacro{setcharacterkerning} /
+         \texmacro{definecharacterkerning} \& al.) functionality of
+         Context, see the file \fileent{typo-krn.lua} there.
+         %
+         The main difference is that \identifier{luaotfload} does not
+         use \LUATEX attributes to assign letterspacing to regions,
+         but defines virtual letterspaced versions of a font.
+
+         The option \identifier{kernfactor} accepts a numeric value that
+         determines the letterspacing factor to be applied to the font
+         size.
+         %
+         E.~g. a kern factor of $0.42$ applied to a $10$ pt font
+         results in $4.2$ pt of additional kerning applied to each
+         pair of glyphs.
+         %
+         Ligatures are split into their component glyphs unless
+         explicitly ignored (see below).
+
+         For compatibility with \XETEX an alternative
+         \identifier{letterspace} option is supplied that interprets the
+         supplied value as a \emphasis{percentage} of the font size but
+         is otherwise identical to \identifier{kernfactor}.
+         %
+         Consequently, both definitions in below snippet yield the same
+         letterspacing width:
+
+         \beginlisting
+    \font \iwonakernedA = "file:Iwona-Regular.otf:kernfactor=0.125"
+    \font \iwonakernedB = "file:Iwona-Regular.otf:letterspace=12.5"
+         \endlisting
+
+         Specific pairs of letters and ligatures may be exempt from
+         letterspacing by defining the \LUA functions
+         \luaident{keeptogether} and \luaident{keepligature},
+         respectively, inside the namespace \inlinecode {luaotfload.letterspace}.
+         %
+         Both functions are called whenever the letterspacing callback
+         encounters an appropriate node or set of nodes.
+         %
+         If they return a true-ish value, no extra kern is inserted at
+         the current position.
+         %
+         \luaident{keeptogether} receives a pair of consecutive
+         glyph nodes in order of their appearance in the node list.
+         %
+         \luaident{keepligature} receives a single node which can be
+         analyzed into components.
+         %
+         (For details refer to the \emphasis{glyph nodes} section in the
+         \LUATEX reference manual.)
+         %
+         The implementation of both functions is left entirely to the
+         user.
+  \endaltitem
+
+\iffalse
+  \startbuffer [printvectors]
+  \directlua{inspect(fonts.protrusions.setups.default)
+             inspect(fonts.expansions.setups.default)}
+  \stopbuffer
+\fi
+
+  \beginaltitem {protrusion \& expansion}
+         These keys control microtypographic features of the font,
+         namely \emphasis{character protrusion} and \emphasis{font
+         expansion}.
+         %
+         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{luaotfload-fonts-ext.lua} where the
+            default values are defined.
+            %
+            Alternatively and with loss of information, you can dump
+            those tables into your terminal by issuing
+            \unless \iffalse
+              \beginlisting
+ \directlua{inspect(fonts.protrusions.setups.default)
+            inspect(fonts.expansions.setups.default)}
+              \endlisting
+            \else
+              \typebuffer [printvectors]
+            \fi
+            at some point after loading \fileent{luaotfload.sty}.
+         }
+         %
+         For both, only the set \identifier{default} is predefined.
+
+         For example, to define a font with the default
+         protrusion vector applied\footnote{%
+           You also need to set
+               \inlinecode {pdfprotrudechars=2} and
+               \inlinecode {pdfadjustspacing=2}
+           to activate protrusion and expansion, respectively.
+           See the
+           \hyperlink [\PDFTEX manual]{http://mirrors.ctan.org/systems/pdftex/manual/pdftex-a.pdf}%
+           for details.
+         }:
+
+         \beginlisting
+      \font \test = LatinModernRoman:protrusion=default
+         \endlisting
+  \endaltitem
+\enddescriptions
+
+\endsubsection
+
+\beginsubsection {Non-standard font features}
+\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 (2014) there are three of them:
+
+\begindescriptions
+
+  \beginaltitem {anum}
+          Substitutes the glyphs in the \abbrev{ascii} number range
+          with their counterparts from eastern Arabic or Persian,
+          depending on the value of \identifier{language}.
+  \endaltitem
+
+  \beginaltitem {tlig}
+          Applies legacy \TEX ligatures\footnote{%
+            These contain the feature set \inlinecode {trep} of earlier
+            versions of \identifier{luaotfload}.
+
+            Note to \XETEX users: this is the equivalent of the
+            assignment \inlinecode {mapping=text-tex} using \XETEX's input
+            remapping feature.
+          }:
+
+          \unless \iffalse
+            %% Using braced arg syntax with inline code appears to be
+            %% impossible within Latex tables -- just ignore the weird
+            %% exclamation points below.
+            \begintabulate [rlrl]
+              \beginrow ``  \newcell  {\inlinecode !``! } \newcell  ''  \newcell  {\inlinecode !''!} \endrow
+              \beginrow `   \newcell  {\inlinecode !`!  } \newcell  '   \newcell  {\inlinecode !'! } \endrow
+              \beginrow "   \newcell  {\inlinecode !"!  } \newcell  --  \newcell  {\inlinecode !--!} \endrow
+              \beginrow --- \newcell  {\inlinecode !---!} \newcell  !`  \newcell  {\inlinecode ?!`?} \endrow
+              \beginrow ?`  \newcell  {\inlinecode !?`! } \newcell      \newcell                     \endrow
+            \endtabulate
+          \else
+            %% XXX find a way to wrap these in the tabulate environment
+            \startframed [frame=off,width=broad,align=middle]
+              \startframed [frame=off,width=\dimexpr(\textwidth/2)]
+                \startxtable [align=middle]
+                    \startxrow \startxcell ``  \stopxcell \startxcell  \inlinecode {``}  \stopxcell \startxcell  ''  \stopxcell \startxcell  \inlinecode {''}  \stopxcell \stopxrow
+                    \startxrow \startxcell `   \stopxcell \startxcell  \inlinecode {`}   \stopxcell \startxcell  '   \stopxcell \startxcell  \inlinecode {'}   \stopxcell \stopxrow
+                    \startxrow \startxcell "   \stopxcell \startxcell  \inlinecode {"}   \stopxcell \startxcell  --  \stopxcell \startxcell  \inlinecode {--}  \stopxcell \stopxrow
+                    \startxrow \startxcell --- \stopxcell \startxcell  \inlinecode {---} \stopxcell \startxcell  !`  \stopxcell \startxcell  \inlinecode {!`}  \stopxcell \stopxrow
+                    \startxrow \startxcell ?`  \stopxcell \startxcell  \inlinecode {?`}  \stopxcell \startxcell      \stopxcell \startxcell                    \stopxcell \stopxrow
+                \stopxtable
+              \stopframed
+            \stopframed
+          \fi
+  \endaltitem
+
+  \beginaltitem {itlc}
+          Computes italic correction values (active by default).
+  \endaltitem
+
+\enddescriptions
+
+\endsubsection
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Combining fonts}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Version 2.7 and later support combining characters from multiple fonts into a
+single virtualized one. This requires that the affected fonts be loaded in
+advance as well as a special \emphasis{request syntax}. Furthermore, this
+allows to define \emphasis{fallback fonts} to supplement fonts that may lack
+certain required glyphs.
+
+Combinations are created by defining a font using the \luaident{combo:} prefix.
+
+\beginsubsection {Fallbacks}
+
+For example, the \identifier{Latin Modern} family of fonts does, as indicated
+in the name, not provide Cyrillic glyphs. If Latin script dominates in the copy
+with interspersed Cyrillic, a fallback can be created from a similiar looking
+font like \identifier{Computer Modern Unicode}, taking advantage of the fact
+that it too derives from Knuth’s original \identifier{Computer Modern} series:
+
+\beginlisting
+  \input luaotfload.sty
+  \font \lm  = file:lmroman10-regular.otf:mode=base
+  \font \cmu = file:cmunrm.otf:mode=base
+  \font \lmu = "combo: 1->\fontid\lm; 2->\fontid\cmu,fallback"
+  \lmu Eh bien, mon prince. Gênes et Lueques ne sont plus que des
+       apanages, des поместья, de la famille Buonaparte.
+  \bye
+\endlisting
+
+As simple as this may look on the first glance, this approach is entirely
+inappropriate if more than a couple letters are required from a different font.
+Because the combination pulls nothing except the glyph data, all of the
+important other information that constitute a proper font -- kerning, styles,
+features, and suchlike -- will be missing.
+
+\endsubsection %% Fallbacks
+
+\beginsubsection {Combinations}
+
+Generalizing the idea of a \emphasis{fallback font}, it is also possible to
+pick definite sets of glyphs from multiple fonts. On a bad day, for instance,
+it may be the sanest choice to start out with \identifier{EB Garamond} italics,
+typeset all decimal digits in the bold italics of \identifier{GNU Freefont},
+and tone down the punctuation with extra thin glyphs from \identifier{Source
+Sans}:
+
+\beginlisting
+  \def \feats     {-tlig;-liga;mode=base;-kern}
+  \def \fileone   {EBGaramond12-Italic.otf}
+  \def \filetwo   {FreeMonoBoldOblique.otf}
+  \def \filethree {SourceSansPro-ExtraLight.otf}
+
+  \input luaotfload.sty
+
+  \font \one   = file:\fileone  :\feats
+  \font \two   = file:\filetwo  :\feats
+  \font \three = file:\filethree:\feats
+
+  \font \onetwothree = "combo:  1 -> \fontid\one;
+                                2 -> \fontid\two,   0x30-0x39;
+                                3 -> \fontid\three, 0x21*0x3f; "
+
+  {\onetwothree \TeX—0123456789—?!}
+  \bye
+\endlisting
+
+\noindent Despite the atrocious result, the example demonstrates well the
+syntax that is used to specify ranges and fonts. Fonts are being referred to by
+their internal index which can be obtained by passing the font command into the
+\texmacro{fontid} macro, e. g. \inlinecode{\fontid\one}, after a font has been
+defined. The first component of the combination is the base font which will be
+extended by the others. It is specified by the index alone.
+
+All further fonts require either the literal \inlinecode{fallback} or a list of
+codepoint definitions to be appended after a comma. The elements of this list
+again denote either single codepoints like \inlinecode{0x21} (referring to the
+exclamation point character) or ranges of codepoints (\inlinecode{0x30-0x39}).
+Elements are separated by the \identifier{ASCII} asterisk character
+(\inlinecode{*}). The characters referenced in the list will be imported from
+the respective font, if available.
+
+\endsubsection %% Combinations
+
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Font names database}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\label{sec:fontdb}
+
+As mentioned above, \identifier{luaotfload} keeps track of which
+fonts are available to \LUATEX by means of a \emphasis{database}.
+%
+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 \hyperlink[\fileent{otfinfo}]{http://www.lcdf.org/type/}
+  (comes with \TEX Live), when invoked on a font file with the
+  \inlinecode {-i} option, lists the variety of name fields defined for
+  it.
+}
+
+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
+recently.
+%
+As soon as the database is updated, the resolver will try
+and look up the font again, all without user intervention.
+%
+The goal is for \identifier{luaotfload} to act in the background and
+behave as unobtrusively as possible, while providing a convenient
+interface to the fonts installed on the system.
+
+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.
+
+\beginsubsection[luaotfload-tool]
+                {\fileent{luaotfload-tool}}
+
+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{luaotfload-tool} that offers an interface to the database
+functionality.
+%
+Being a \LUA script, there are two ways to run it:
+either make it executable (\inlinecode {chmod +x} on unixoid systems) or
+pass it as an argument to \fileent{texlua}.\footnote{%
+  Tests by the maintainer show only marginal performance gain by
+  running with Luigi Scarso’s
+  \hyperlink [\identifier{Luajit\kern-.25ex\TEX}]{https://foundry.supelec.fr/projects/luajittex/},
+  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{luaotfload-tool.exe} or as
+  \inlinecode {texlua.exe luaotfload-tool.lua}.
+}
+%
+Invoked with the argument \inlinecode {--update} it will perform a database
+update, scanning for fonts not indexed.
+
+\beginlisting
+  luaotfload-tool --update
+\endlisting
+
+Adding the \inlinecode {--force} switch will initiate a complete
+rebuild of the database.
+
+\beginlisting
+  luaotfload-tool --update --force
+\endlisting
+
+\endsubsection
+
+\beginsubsection{Search Paths}
+
+\identifier{luaotfload} scans those directories where fonts are
+expected to be located on a given system.
+%
+On a Linux machine it follows the paths listed in the
+\identifier{Fontconfig} configuration files;
+consult \inlinecode {man 5 fonts.conf} for further information.
+%
+On \identifier{Windows} systems, the standard location is
+\inlinecode {Windows\\Fonts},
+%
+while \identifier{Mac OS~X} requires a multitude of paths to
+be examined.
+%
+The complete list is is given in table \ref{table-searchpaths}.
+Other paths can be specified by setting the environment variable
+\inlinecode {OSFONTDIR}.
+%
+If it is non-empty, then search will be extended to the included
+directories.
+
+\tablefloat {table-searchpaths}
+  {List of paths searched for each supported operating system.}
+  {%
+    \unless \iffalse
+      \begincentered
+        \begintabulate [lp{.5\textwidth}]
+          \beginrow
+            Windows   \newcell \inlinecode !\% WINDIR\%\\ Fonts!
+          \endrow
+          \beginrow
+            Linux     \newcell \fileent{/usr/local/etc/fonts/fonts.conf} and\hfill\break
+                               \fileent{/etc/fonts/fonts.conf}
+          \endrow
+          \beginrow
+            Mac       \newcell \fileent{\textasciitilde/Library/Fonts},\break
+                               \fileent{/Library/Fonts},\break
+                               \fileent{/System/Library/Fonts}, and\hfill\break
+                               \fileent{/Network/Library/Fonts}
+          \endrow
+        \endtabulate
+      \endcentered
+    \else
+      \setuplocalinterlinespace [14pt]
+      \starttabulate [|l|p(.5\textwidth)|]
+        \NC Windows   \NC \inlinecode {\% WINDIR\%\\ Fonts} \NC \NR
+        \NC Linux     \NC \fileent{/usr/local/etc/fonts/fonts.conf} and\crlf
+                          \fileent{/etc/fonts/fonts.conf} \NC \NR
+        \NC
+          Mac         \NC \fileent{\textasciitilde/Library/Fonts},\crlf
+                          \fileent{/Library/Fonts},\break
+                          \fileent{/System/Library/Fonts}, and\crlf
+                          \fileent{/Network/Library/Fonts} \NC \NR
+      \stoptabulate
+    \fi%
+  }
+
+\endsubsection
+
+\beginsubsection{Querying from Outside}
+
+\fileent{luaotfload-tool} also provides rudimentary means of
+accessing the information collected in the font database.
+%
+If the option \inlinecode {--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
+
+\beginlisting
+  luaotfload-tool  --find="Iwona Regular"
+\endlisting
+
+\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 add the
+\inlinecode {-F} (or \inlinecode {--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
+
+\beginlisting
+  luaotfload-tool  -F --find="Iwona Bright"
+\endlisting
+
+\noindent
+will tell you that indeed the latter name is correct.
+
+Basic information about fonts in the database can be displayed
+using the \inlinecode {-i} option (\inlinecode {--info}).
+%
+\beginlisting
+  luaotfload-tool  -i --find="Iwona Light Italic"
+\endlisting
+%
+\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}.
+}
+
+For a much more detailed report about a given font try the
+\inlinecode {-I} option instead (\inlinecode {--inspect}).
+\beginlisting
+  luaotfload-tool  -I --find="Iwona Light Italic"
+\endlisting
+
+\inlinecode {luaotfload-tool --help} will list the available command line
+switches, including some not discussed in detail here.
+%
+For a full documentation of \identifier{luaotfload-tool} and its
+capabilities refer to the manpage
+(\inlinecode {man 1 luaotfload-tool}).\footnote{%
+  Or see \inlinecode {luaotfload-tool.rst} in the source directory.
+}
+
+\endsubsection
+
+\beginsubsection {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 \inlinecode {luaotfload-tool -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{luaotfload-blacklist.cnf}.
+
+A blacklist file is a list of font filenames, one per line.
+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 (\inlinecode {\%}) character until the end of the line
+is ignored, so use this to add comments.
+%
+Place this file to some location where the \identifier{kpse}
+library can find it, e.~g.
+\fileent{texmf-local/tex/luatex/luaotfload} if you are running
+\identifier{\TEX Live},\footnote{%
+  You may have to run \inlinecode {mktexlsr} if you created a new file in
+  your \fileent{texmf} tree.
+}
+or just leave it in the working directory of your document.
+%
+\identifier{luaotfload} reads all files named
+\fileent{luaotfload-blacklist.cnf} it finds, so the fonts in
+\fileent{./luaotfload-blacklist.cnf} extend the global blacklist.
+
+Furthermore, a filename prepended with a dash character (\inlinecode{-}) is
+removed from the blacklist, causing it to be temporarily whitelisted
+without modifying the global file.
+%
+An example with explicit paths:
+
+\beginlisting
+% example otf-blacklist.cnf
+/Library/Fonts/GillSans.ttc  % Luaotfload ignores this font.
+-/Library/Fonts/Optima.ttc   % This one is usable again, even if
+                             % blacklisted somewhere else.
+\endlisting
+
+\endsubsection
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {The Fontloader}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\beginsubsection {Overview}
+
+To a large extent, \identifier{luaotfload} relies on code originally
+written by Hans Hagen for the
+\hyperlink[\identifier{\CONTEXT}]{http://wiki.contextgarden.net}
+format.
+%
+It integrates the font loader, written entirely in \LUA, as distributed
+in the \identifier{\LUATEX-Fonts} package.
+%
+The original \LUA source files have been combined using the \CONTEXT
+packaging library into a single, self-contained blob. In
+this form the font loader depends only on the \identifier{lualibs}
+package and requires only minor adaptions to integrate into
+\identifier{luaotfload}.
+
+The guiding principle is to let \CONTEXT/\LUATEX-Fonts take care of the
+implementation, and update the imported code as frequently as
+necessary.
+%
+As maintainers, we aim at importing files from upstream essentially
+\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
+manually spotted and extracted from the \CONTEXT source code in a
+complicated and error-prone fashion.
+
+\endsubsection
+
+\beginsubsection {Contents and Dependencies}
+
+Below is a commented list of the files distributed with
+\identifier{luaotfload} in one way or the other.
+%
+See see the figure on page \pageref{file-graph} for a
+graphical representation of the dependencies.
+%
+\label{package}%
+Through the script \fileent{mkimport} a \CONTEXT library
+is invoked to create the \identifier{luaotfload} fontloader as a merged
+(amalgamated) source file.\footnote{%
+  In \CONTEXT, this facility can be accessed by means of a
+  \hyperlink[script]{https://bitbucket.org/phg/context-mirror/src/beta/scripts/context/lua/mtx-package.lua?at=beta}
+  which is integrated into \fileent{mtxrun} as a subcommand.
+  Run \inlinecode {mtxrun --script package --help} to display further
+  information.
+  For the actual merging code see the file
+  \fileent{util-mrg.lua} that is part of \CONTEXT.
+}
+%
+This file constitutes the “default fontloader” and is part of the
+\identifier{luaotfload} package as \fileent{fontloader-YY-MM-DD.lua},
+where the uppercase letters are placeholders for the build date.
+%
+A companion to it, \fileent{luatex-basics-gen.lua} (renamed to \fileent{fontloader-basics-gen.lua} in \identifier{luaotfload})
+must be loaded beforehand to set up parts of the environment required by the \CONTEXT
+libraries.
+%
+During a \TEX\ run, the fontloader initialization and injection happens
+in the module \fileent{luaotfload-init.lua}.
+%
+Additionally, the “reference fontloader” as imported from \LUATEX-Fonts
+is provided as the file \fileent{fontloader-reference.lua}.
+%
+This file is self-contained in that it packages all the auxiliary \LUA
+libraries too, as Luaotfload did up to the 2.5 series; since that job
+has been offloaded to the \identifier{Lualibs} package, loading this
+fontloader introduces a certain code duplication.
+
+A number of \emphasis{\LUA utility libraries} are not part of the
+\identifier{luaotfload} fontloader, contrary to its equivalent in
+\LUATEX-Fonts. These are already provided by the \identifier{lualibs}
+and have thus been omitted from the merge.\footnote{%
+  Faithful listeners will remember the pre-2.6 era when the fontloader
+  used to be integrated as-is which caused all kinds of code
+  duplication with the pervasive \identifier{lualibs} package.
+  This conceptual glitch has since been amended by tightening the
+  coupling with the excellent \CONTEXT\ toolchain.
+}
+
+\begindoublecolumns
+  \begindefinitions
+ \directlua{ printctxlibslist ()}
+  \enddefinitions
+\enddoublecolumns
+
+The reference fontloader is home to several \LUA files that can be
+grouped twofold as below:
+
+\begindefinitions
+  \beginnormalitem
+    The \emphasis{font loader} itself.
+    These files have been written for \LUATEX-Fonts and they are
+    distributed along with \identifier{luaotfload} so as to resemble
+    the state of the code when it was imported. Their purpose is either
+    to give a slightly aged version of a file if upstream considers
+    latest developments for not yet ready for use outside Context; or,
+    to install placeholders or minimalist versions of APIs relied upon
+    but usually provided by parts of Context not included in the
+    fontloader.
+    \begindoublecolumns
+      \begindefinitions
+        \directlua{printctxallgenericlist ()}
+      \enddefinitions
+    \enddoublecolumns
+  \endnormalitem
+
+  \beginnormalitem
+    Code related to \emphasis{font handling and node processing}, taken
+    directly from \CONTEXT.
+    \begindoublecolumns
+      \begindefinitions
+      \directlua{printctxfontlist ()}
+      \enddefinitions
+    \enddoublecolumns
+  \endnormalitem
+\enddefinitions
+
+As an alternative to the merged file, \identifier {Luaotfload} may load
+individual unpackaged \LUA libraries that come with the source, or even
+use the files from Context directly.
+%
+Thus if you prefer running bleeding edge code from the \CONTEXT beta,
+choose the \inlinecode {context} fontloader via the configuration file
+(see sections \ref{sec:conf} and \ref{sec:pkg} below).
+
+Also, the merged file at some point loads the Adobe Glyph List from a
+\LUA table that is contained in \fileent{luaotfload-glyphlist.lua},
+which is automatically generated by the script
+\fileent{mkglyphlist}.\footnote{%
+  See \fileent{luaotfload-font-enc.lua}.
+  The hard-coded file name is why we have to replace the procedure
+  that loads the file in \fileent{luaotfload-init.lua}.
+}
+%
+There is a make target \identifier{glyphs} that will create a fresh
+glyph list so we don’t need to import it from \CONTEXT any longer.
+
+In addition to these, \identifier{luaotfload} requires a number of
+files not contained in the merge. Some of these have no equivalent in
+\LUATEX-Fonts or \CONTEXT, some were taken unmodified from the latter.
+
+
+\beginfilelist
+    \beginaltitem {luaotfload-features.lua}
+      font feature handling; incorporates some of the code from
+      \fileent{font-otc} from \CONTEXT;
+    \endaltitem
+    \beginaltitem {luaotfload-configuration.lua}
+      handling of \fileent{luaotfload.conf(5)}.
+    \endaltitem
+    \beginaltitem {luaotfload-log.lua}
+      overrides the \CONTEXT logging functionality.
+    \endaltitem
+    \beginaltitem {luaotfload-loaders.lua}
+      registers readers in the fontloader for various kinds of
+      font formats
+    \endaltitem
+    \beginaltitem {luaotfload-parsers.lua}
+      various \abbrev{lpeg}-based parsers.
+    \endaltitem
+    \beginaltitem {luaotfload-database.lua}
+      font names database.
+    \endaltitem
+    \beginaltitem {luaotfload-resolvers.lua}
+      file name resolvers.
+    \endaltitem
+    \beginaltitem {luaotfload-colors.lua}
+      color handling.
+    \endaltitem
+    \beginaltitem {luaotfload-auxiliary.lua}
+      access to internal functionality for package authors (proposals
+      for additions welcome).
+    \endaltitem
+    \beginaltitem {luaotfload-letterspace.lua}
+      font-based letterspacing.
+    \endaltitem
+        \beginaltitem {luaotfload-filelist.lua}
+      data about the files in the package.
+    \endaltitem
+\endfilelist
+
+%\figurefloat
+%  {file-graph}
+%  {Schematic of the files in \identifier{Luaotfload}}
+%  {filegraph.pdf}
+
+\endsubsection
+
+\beginsubsection {Packaging}
+
+\label{sec:pkg}%
+The fontloader code is integrated as an isolated component that can be
+switched out on demand.
+%
+To specify the fontloader you wish to use, the configuration file
+(described in section \ref{sec:conf}) provides the option
+\inlinecode{fontloader}.
+%
+Its value can be one of the identifiers \inlinecode{default} or
+\inlinecode{reference} (see above, section \ref{package}) or the name
+of a file somewhere in the search path of \LUATEX.
+%
+This will make \identifier {Luaotfload} locate the \CONTEXT source by
+means of \identifier{kpathsea} lookups and use those instead of the
+merged package.
+%
+The parameter may be extended with a path to the \CONTEXT
+\fileent{texmf}, separated with a colon:
+
+\beginlisting
+[run]
+  fontloader = context:~/context/tex/texmf-context
+\endlisting
+
+\noindent This setting allows accessing an installation -- e. g. the
+standalone distribution or a source repository -- outside the current
+\TEX distribution.
+
+Like the \identifier{Lualibs} package, the fontloader is deployed as a
+\emphasis{merged package} containing a series of \LUA files joined
+together in their expected order and stripped of non-significant parts.
+%
+The \fileent{mkimport} utility assists in pulling the files from a
+\CONTEXT tree and packaging them for use with \identifier{Luaotfload}.%
+%
+The state of the files currently in \identifier{Luaotfload}’s
+repository can be queried:
+\beginlisting
+./scripts/mkimport news
+\endlisting
+%
+The subcommand for importing takes the prefix of the desired \CONTEXT
+\identifier{texmf} as an optional argument:
+\beginlisting
+./scripts/mkimport import ~/context/tex/texmf-context
+\endlisting
+%
+Whereas the command for packaging requires a path to the
+\emphasis{package description file} and the output name to be passed.
+\beginlisting
+./scripts/mkimport package fontloader-custom.lua
+\endlisting
+
+From the toplevel makefile, the targets \inlinecode{import} and
+\inlinecode{package} provide easy access to the commands as invoked during
+the \identifier{Luaotfload} build process.\footnote{%
+  \emphasis{Hint for those interested in the packaging process}: issue
+  \inlinecode{make show} for a list of available build routines.
+}
+These will call \inlinecode{mkimport} script with the correct
+parameters to generate a datestamped package.
+%
+Whether files have been updated in the upstream distribution can be
+queried by \inlinecode{./scripts/mkimport news}.
+%
+This will compare the imported files with their counterparts in the
+\CONTEXT distribution and report changes.
+
+\endsubsection
+
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Configuration Files}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\beginnarrower
+  \emphasis{Caution}: For the authoritative documentation, consult the
+  manpage for \fileent{luaotfload.conf(5)}.
+\endnarrower
+
+\label{sec:conf}
+The runtime behavior of \identifier{Luaotfload} can be customized by
+means of a configuration file.
+% location
+At startup, it attempts to locate a file called \fileent
+{luaotfload.conf} or \fileent {luaotfloadrc} at a number of candidate
+locations:
+
+\begincentered
+  \begindefinitions
+    \beginnormalitem \fileent{./luaotfload.conf}                            \endnormalitem
+    \beginnormalitem \fileent{./luaotfloadrc}                               \endnormalitem
+    \beginnormalitem \fileent{\$XDG_CONFIG_HOME/luaotfload/luaotfload.conf} \endnormalitem
+    \beginnormalitem \fileent{\$XDG_CONFIG_HOME/luaotfload/luaotfload.rc}   \endnormalitem
+    \beginnormalitem \fileent{~/.luaotfloadrc}                              \endnormalitem
+  \enddefinitions
+\endcentered
+
+\beginnarrower
+  \emphasis{Caution}: The configuration potentially modifies the final
+  document. A project-local file belongs under version control along
+  with the rest of the document. This is to ensure that everybody who
+  builds the project also receives the same customizations as the
+  author.
+\endnarrower
+
+% syntax
+The syntax is fairly close to the format used by
+\fileent{git-config(1)} which in turn was derived from the popular
+\identifier{.INI} format: Lines of key-value pairs are grouped under
+different configuration “sections”.\footnote{%
+  The configuration parser in \fileent {luoatfload-parsers.lua} might
+  be employed by other packages for similar purposes.
+}
+% example settings
+An example for customization via \fileent {luaotfload.conf} might look
+as below:
+
+\beginlisting
+; Example luaotfload.conf containing a rudimentary configuration
+[db]
+  update-live = false
+[run]
+  color-callback = pre_linebreak_filter
+  definer = info_patch
+  log-level = 5
+[default-features]
+  global = mode=base
+\endlisting
+
+This specifies that for the given project, \identifier{Luaotfload}
+shall not attempt to automatically scan for fonts if it can’t resolve a
+request. The font-based colorization will happen during \LUATEX’s
+pre-linebreak filter. The fontloader will output verbose information
+about the fonts at definition time along with globally increased
+verbosity. Lastly, the fontloader defaults to the less expensive
+\luaident{base} mode like it does in \CONTEXT.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Auxiliary Functions}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+With release version 2.2, \identifier{Luaotfload} received
+additional functions for package authors to call from outside
+(see the file \fileent{luaotfload-auxiliary.lua} for details).
+%
+The purpose of this addition twofold.
+%
+Firstly, \identifier{luaotfload} failed to provide a stable interface
+to internals in the past which resulted in an unmanageable situation
+of different packages abusing the raw access to font objects by means
+of the \luaident{patch_font} callback.
+%
+When the structure of the font object changed due to an update, all
+of these imploded and several packages had to be fixed while
+simultaneously providing fallbacks for earlier versions.
+%
+Now the patching is done on the \identifier{luaotfload} side and can
+be adapted with future modifications to font objects without touching
+the packages that depend on it.
+%
+Second, some the capabilities of the font loader and the names
+database are not immediately relevant in \identifier{luaotfload}
+itself but might nevertheless be of great value to package authors or
+end users.
+
+Note that the current interface is not yet set in stone and the
+development team is open to suggestions for improvements or
+additions.
+
+\beginsubsection {Callback Functions}
+
+The \luaident{patch_font} callback is inserted in the wrapper
+\identifier{luaotfload} provides for the font definition callback.
+%
+At this place it allows manipulating the font object immediately after
+the font loader is done creating it.
+%
+For a short demonstration of its usefulness, here is a snippet that
+writes an entire font object to the file \fileent{fontdump.lua}:
+
+\beginlisting
+  \input luaotfload.sty
+  \directlua{
+    local dumpfile    = "fontdump.lua"
+    local dump_font   = function (tfmdata)
+      local data = table.serialize(tfmdata)
+      io.savedata(dumpfile, data)
+    end
+
+    luatexbase.add_to_callback(
+      "luaotfload.patch_font",
+      dump_font,
+      "my_private_callbacks.dump_font"
+    )
+  }
+  \font \dumpme = name:Iwona
+  \bye
+\endlisting
+
+\emphasis{Beware}: this creates a Lua file of around 150,000 lines of
+code, taking up 3~\abbrev{mb} of disk space.
+%
+By inspecting the output you can get a first impression of how a font
+is structured in \LUATEX’s memory, what elements it is composed of,
+and in what ways it can be rearranged.
+
+\beginsubsubsection {Compatibility with Earlier Versions}
+
+As has been touched on in the preface to this section, the structure
+of the object as returned by the fontloader underwent rather drastic
+changes during different stages of its development, and not all
+packages that made use of font patching have kept up with every one
+of it.
+%
+To ensure compatibility with these as well as older versions of
+some packages, \identifier{luaotfload} sets up copies of or references
+to data in the font table where it used to be located.
+%
+For instance, important parameters like the requested point size, the
+units factor, and the font name have again been made accessible from
+the toplevel of the table even though they were migrated to different
+subtables in the meantime.
+
+\endsubsubsection
+
+\beginsubsubsection{Patches}
+
+These are mostly concerned with establishing compatibility with \XETEX.
+
+\beginfunctionlist
+
+  \beginaltitem  {set_sscale_dimens}
+    Calculate \texmacro{fontdimen}s 10 and 11 to emulate \XETEX.
+  \endaltitem
+
+  \beginaltitem  {set_capheight}
+    Calculates \texmacro{fontdimen} 8 like \XETEX.
+  \endaltitem
+
+  \beginaltitem  {patch_cambria_domh}
+    Correct some values of the font \emphasis{Cambria Math}.
+  \endaltitem
+
+\endfunctionlist
+
+\endsubsection
+
+\beginsubsection {Package Author’s Interface}
+
+As \LUATEX release 1.0 is nearing, the demand for a reliable interface
+for package authors increases.
+
+\endsubsubsection
+
+\beginsubsubsection{Font Properties}
+
+Below functions mostly concern querying the different components of a
+font like for instance the glyphs it contains, or what font features
+are defined for which scripts.
+
+\beginfunctionlist
+
+  \beginaltitem  {aux.font_has_glyph (id : int, index : int)}
+            Predicate that returns true if the font \luaident{id}
+            has glyph \luaident{index}.
+  \endaltitem
+
+  \beginaltitem  {aux.slot_of_name(name : string)}
+            Translates an Adobe Glyph name to the corresponding glyph
+            slot.
+  \endaltitem
+
+  \beginaltitem  {aux.name_of_slot(slot : int)}
+            The inverse of \luaident{slot_of_name}; note that this
+            might be incomplete as multiple glyph names may map to the
+            same codepoint, only one of which is returned by
+            \luaident{name_of_slot}.
+  \endaltitem
+
+  \beginaltitem  {aux.provides_script(id : int, script : string)}
+            Test if a font supports \luaident{script}.
+  \endaltitem
+
+  \beginaltitem  {aux.provides_language(id : int, script : string, language : string)}
+            Test if a font defines \luaident{language} for a given
+            \luaident{script}.
+  \endaltitem
+
+  \beginaltitem  {aux.provides_feature(id : int, script : string,
+             language : string, feature : string)}
+            Test if a font defines \luaident{feature} for
+            \luaident{language} for a given \luaident{script}.
+  \endaltitem
+
+  \beginaltitem  {aux.get_math_dimension(id : int, dimension : string)}
+            Get the dimension \luaident{dimension} of font \luaident{id}.
+  \endaltitem
+
+  \beginaltitem  {aux.sprint_math_dimension(id : int, dimension : string)}
+            Same as \luaident{get_math_dimension()}, but output the value
+            in scaled points at the \TEX end.
+  \endaltitem
+
+\endfunctionlist
+
+\endsubsubsection
+
+\beginsubsubsection{Database}
+
+%% not implemented, may come back later
+\beginfunctionlist
+%   \beginaltitem  {aux.scan_external_dir(dir : string)}
+%             Include fonts in directory \luaident{dir} in font lookups without
+%             adding them to the database.
+%
+  \beginaltitem  {aux.read_font_index (void)}
+            Read the index file from the appropriate location (usually
+            the bytecode file \fileent{luaotfload-names.luc} somewhere
+            in the \fileent{texmf-var} tree) and return the result as a
+            table. The file is processed with each call so it is up to
+            the user to store the result for later access.
+  \endaltitem
+
+  \beginaltitem  {aux.font_index (void)}
+            Return a reference of the font names table used internally
+            by \identifier{luaotfload}. The index will be read if it
+            has not been loaded up to this point. Also a font scan that
+            overwrites the current index file might be triggered. Since
+            the return value points to the actual index, any
+            modifications to the table might influence runtime behavior
+            of \identifier{luaotfload}.
+  \endaltitem
+
+\endfunctionlist
+
+\endsubsubsection
+
+\endsubsection
+\endsection
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\beginsection {Troubleshooting}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\beginsubsection {Database Generation}
+
+If you encounter problems with some fonts, please first update to the
+latest version of this package before reporting a bug, as
+\identifier{luaotfload} is under active development and still a moving
+target.
+%
+The development takes place on \identifier{github} at
+\hyperlink {https://github.com/lualatex/luaotfload} where there is an issue
+tracker for submitting bug reports, feature requests and the likes.
+
+Bug reports are more likely to be addressed if they contain the output
+of
+
+\beginlisting
+    luaotfload-tool --diagnose=environment,files,permissions
+\endlisting
+
+\noindent Consult the man page for a description of these options.
+
+Errors during database generation can be traced by increasing the
+verbosity level and redirecting log output to \fileent{stdout}:
+
+\beginlisting
+    luaotfload-tool -fuvvv --log=stdout
+\endlisting
+
+\noindent or to a file in \fileent{/tmp}:
+
+\beginlisting
+    luaotfload-tool -fuvvv --log=file
+\endlisting
+
+\noindent In the latter case, invoke the \inlinecode {tail(1)} utility on the
+file for live monitoring of the progress.
+
+If database generation fails, the font last printed to the terminal or
+log file is likely to be the culprit.
+%
+Please specify it when reporting a bug, and blacklist it for the time
+being (see above, page \pageref{font-blacklist}).
+
+\endsubsection
+
+\beginsubsection {Font Features}
+
+A common problem is the lack of features for some
+\OpenType fonts even when specified.
+%
+This can be related to the fact that some fonts do not provide features
+for the \inlinecode {dflt} script (see above on page \pageref{script-tag}),
+which is the default one in this package.
+%
+If this happens, assigning a noth script when the font is defined should
+fix it.
+%
+For example with \inlinecode {latn}:
+
+\beginlisting
+    \font \test = file:MyFont.otf:script=latn;+liga;
+\endlisting
+
+You can get a list of features that a font defines for scripts and
+languages by querying it in \fileent{luaotfload-tool}:
+
+\beginlisting
+    luaotfload-tool --find="Iwona" --inspect
+\endlisting
+
+\endsubsection
+
+\beginsubsection {\LUATEX Programming}
+
+Another strategy that helps avoiding problems is to not access raw
+\LUATEX internals directly.
+%
+Some of them, even though they are dangerous to access, have not been
+overridden or disabled.
+%
+Thus, whenever possible prefer the functions in the \luaident{aux}
+namespace over direct manipulation of font objects. For example, raw
+access to the \luaident{font.fonts} table like:
+
+\beginlisting
+    local somefont = font.fonts[2]
+\endlisting
+
+\noindent can render already defined fonts unusable.
+%
+Instead, the function \luaident{font.getfont()} should be used
+because it has been replaced by a safe variant.
+
+However, \luaident{font.getfont()} only covers fonts handled by the
+font loader, e.~g. \identifier{OpenType} and \identifier{TrueType}
+fonts, but not \abbrev{tfm} or \abbrev{ofm}.
+%
+Should you absolutely require access to all fonts known to \LUATEX,
+including the virtual and autogenerated ones, then you need to query
+both \luaident{font.getfont()} and \luaident{font.fonts}.
+%
+In this case, best define you own accessor:
+
+\beginlisting
+    local unsafe_getfont = function (id)
+        local tfmdata = font.getfont (id)
+        if not tfmdata then
+            tfmdata = font.fonts[id]
+        end
+        return tfmdata
+    end
+
+    --- use like getfont()
+    local somefont = unsafe_getfont (2)
+\endlisting
+
+\endsubsection
+\endsection
+
+\beginsection {License}
+
+\identifier {luaotfload} is licensed under the terms of the
+\hyperlink [GNU General Public License version 2.0]%
+           {https://www.gnu.org/licenses/old-licenses/gpl-2.0.html}.
+Following the underlying fontloader code \identifier {luaotfload}
+recognizes only that exact version as its license.
+The „any later version” clause of the original license text as
+copyrighted by the \hyperlink [Free Software Foundation]{http://www.fsf.org/}
+\emphasis {does not apply} to either \identifier {luaotfload} or the
+code imported from \CONTEXT.
+
+The complete text of the license is given as a separate file \fileent
+{COPYING} in the toplevel directory of the
+\hyperlink [\fileent {Luaotfload} Git repository]{https://github.com/lualatex/luaotfload/blob/master/COPYING}.
+Distributions probably package it as \fileent
+{doc/luatex/luaotfload/COPYING} in the relevant \fileent {texmf} tree.
+
+\endsection
+
+\endinput
+
+% vim:ft=tex:tw=79:et:sw=2


Property changes on: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-main.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf	2018-09-26 20:50:34 UTC (rev 48771)

Property changes on: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.rst	2018-09-26 20:50:34 UTC (rev 48771)
@@ -0,0 +1,328 @@
+=======================================================================
+                            luaotfload-tool
+=======================================================================
+
+-----------------------------------------------------------------------
+         generate and query the Luaotfload font names database
+-----------------------------------------------------------------------
+
+:Date:                  2018-09-21
+:Copyright:             GPL v2.0
+:Version:               2.9
+:Manual section:        1
+:Manual group:          text processing
+
+SYNOPSIS
+=======================================================================
+
+**luaotfload-tool** [ -bcDfFiIlLnpqRSuvVhw ]
+
+**luaotfload-tool** --update [ --force ] [ --quiet ] [ --verbose ]
+                             [ --prefer-texmf ] [ --dry-run ]
+                             [ --formats=[+|-]EXTENSIONS ]
+                             [ --no-compress ] [ --no-strip ]
+                             [ --local ] [ --max-fonts=N ]
+
+**luaotfload-tool** --find=FONTNAME [ --fuzzy ] [ --info ] [ --inspect ]
+                                    [ --no-reload ]
+
+**luaotfload-tool** --flush-lookups
+
+**luaotfload-tool** --cache=DIRECTIVE
+
+**luaotfload-tool** --list=CRITERION[:VALUE] [ --fields=F1,F2,...,Fn ]
+
+**luaotfload-tool** --bisect=DIRECTIVE
+
+**luaotfload-tool** --help
+
+**luaotfload-tool** --version
+
+**luaotfload-tool** --show-blacklist
+
+**luaotfload-tool** --diagnose=CHECK
+
+**luaotfload-tool** --conf=FILE --dumpconf
+
+DESCRIPTION
+=======================================================================
+
+luaotfload-tool accesses the font names database that is required by
+the *Luaotfload* package. There are two general modes: **update** and
+**query**.
+
++ **update**:  update the database or rebuild it entirely;
++ **query**:   resolve a font name or display close matches.
+
+OPTIONS
+=======================================================================
+
+update mode
+-----------------------------------------------------------------------
+--update, -u            Update the database; indexes new fonts.
+--force, -f             Force rebuilding of the database; re-indexes
+                        all fonts.
+--local, -L             Include font files in ``$PWD``. This option
+                        will cause large parts of the database to be
+                        rebuilt. Thus it is quite inefficient.
+                        Additionally, if local font files are found,
+                        the database is prevented from being saved
+                        to disk, so the local fonts need to be parsed
+                        with every invocation of ``luaotfload-tool``.
+--no-reload, -n         Suppress auto-updates to the database (e.g.
+                        when ``--find`` is passed an unknown name).
+--no-compress, -c       Do not filter the plain text version of the
+                        font index through gzip. Useful for debugging
+                        if your editor is built without zlib.
+
+--prefer-texmf, -p      Organize the file name database in a way so
+                        that it prefer fonts in the *TEXMF* tree over
+                        system fonts if they are installed in both.
+--formats=EXTENSIONS    Extensions of the font files to index.
+                        Where *EXTENSIONS* is a comma-separated list of
+                        supported file extensions (otf, ttf, ttc).
+                        If the list is prefixed
+                        with a ``+`` sign, the given list is added to
+                        the currently active one; ``-`` subtracts.
+                        Default: *otf,ttf,ttc*.
+                        Examples:
+
+                        1) ``--formats=-ttc,ttf`` would skip
+                           TrueType fonts and font collections;
+                        2) ``--formats=otf`` would scan only OpenType
+                           files;
+                        3) ``--formats=+afm`` includes binary
+                           Postscript files accompanied by an AFM file.
+
+query mode
+-----------------------------------------------------------------------
+--find=NAME             Resolve a font name; this looks up <name> in
+                        the database and prints the file name it is
+                        mapped to.
+                        ``--find`` also understands request syntax,
+                        i.e. ``--find=file:foo.otf`` checks whether
+                        ``foo.otf`` is indexed.
+--fuzzy, -F             Show approximate matches to the file name if
+                        the lookup was unsuccessful (requires
+                        ``--find``).
+
+--info, -i              Display basic information to a resolved font
+                        file (requires ``--find``).
+--inspect, -I           Display detailed information by loading the
+                        font and analyzing the font table; very slow!
+                        For the meaning of the returned fields see
+                        the LuaTeX documentation.
+                        (requires ``--find``).
+
+--list=CRITERION        Show entries, where *CRITERION* is one of the
+                        following:
+
+                        1) the character ``*``, selecting all entries;
+                        2) a field of a database entry, for instance
+                           *version* or *format**, according to which
+                           the output will be sorted.
+                           Information in an unstripped database (see
+                           the option ``--no-strip`` above) is nested:
+                           Subfields of a record can be addressed using
+                           the ``->`` separator, e. g.
+                           ``file->location``, ``style->units_per_em``,
+                           or
+                           ``names->sanitized->english->prefmodifiers``.
+                           NB: shell syntax requires that arguments
+                           containing ``->`` be properly quoted!
+                        3) an expression of the form ``field:value`` to
+                           limit the output to entries whose ``field``
+                           matches ``value``.
+
+                        For example, in order to output file names and
+                        corresponding versions, sorted by the font
+                        format::
+
+                            ./luaotfload-tool.lua --list="format" --fields="file->base,version"
+
+                        This prints::
+
+                            otf latinmodern-math.otf  Version 1.958
+                            otf lmromancaps10-oblique.otf 2.004
+                            otf lmmono8-regular.otf 2.004
+                            otf lmmonoproplt10-bold.otf 2.004
+                            otf lmsans10-oblique.otf  2.004
+                            otf lmromanslant8-regular.otf 2.004
+                            otf lmroman12-italic.otf  2.004
+                            otf lmsansdemicond10-oblique.otf  2.004
+                            ...
+
+--fields=FIELDS         Comma-separated list of fields that should be
+                        printed.
+                        Information in an unstripped database (see the
+                        option ``--no-strip`` above) is nested:
+                        Subfields of a record can be addressed using
+                        the ``->`` separator, e. g.
+                        ``file->location``, ``style->units_per_em``,
+                        or ``names->sanitized->english->subfamily``.
+                        The default is plainname,version*.
+                        (Only meaningful with ``--list``.)
+
+font and lookup caches
+-----------------------------------------------------------------------
+--flush-lookups         Clear font name lookup cache (experimental).
+
+--cache=DIRECTIVE       Cache control, where *DIRECTIVE* is one of the
+                        following:
+
+                        1) ``purge`` -> delete Lua files from cache;
+                        2) ``erase`` -> delete Lua and Luc files from
+                           cache;
+                        3) ``show``  -> print stats.
+
+debugging methods
+-----------------------------------------------------------------------
+--show-blacklist, -b    Show blacklisted files (not directories).
+--dry-run, -D           Don’t load fonts when updating the database;
+                        scan directories only.
+                        (For debugging file system related issues.)
+--no-strip              Do not strip redundant information after
+                        building the database. Warning: this will
+                        inflate the index to about two to three times
+                        the normal size.
+--max-fonts=N           Process at most *N* font files, including fonts
+                        already indexed in the count.
+--bisect=DIRECTIVE      Bisection of the font database.
+                        This mode is intended as assistance in
+                        debugging the Luatex engine, especially when
+                        tracking memleaks or buggy fonts.
+
+                        *DIRECTIVE* can be one of the following:
+
+                        1) ``run`` -> Make ``luaotfload-tool`` respect
+                           the bisection progress when running.
+                           Combined with ``--update`` and possibly
+                           ``--force`` this will only process the files
+                           from the start up until the pivot and ignore
+                           the rest.
+                        2) ``start`` -> Start bisection: create a
+                           bisection state file and initialize the low,
+                           high, and pivot indices.
+                        3) ``stop`` -> Terminate the current bisection
+                           session by deleting the state file.
+                        4) ``good`` | ``bad`` -> Mark the section
+                           processed last as “good” or “bad”,
+                           respectively. The next bisection step will
+                           continue with the bad section.
+                        5) ``status`` -> Print status information about
+                           the current bisection session. Hint: Use
+                           with higher verbosity settings for more
+                           output.
+
+                        A bisection session is initiated by issuing the
+                        ``start`` directive. This sets the pivot to the
+                        middle of the list of available font files.
+                        Now run *luaotfload-tool* with the ``--update``
+                        flag set as well as ``--bisect=run``: only the
+                        fonts up to the pivot will be considered. If
+                        that task exhibited the issue you are tracking,
+                        then tell Luaotfload using ``--bisect=bad``.
+                        The next step of ``--bisect=run`` will continue
+                        bisection with the part of the files below the
+                        pivot.
+                        Likewise, issue ``--bisect=good`` in order to
+                        continue with the fonts above the pivot,
+                        assuming the tested part of the list did not
+                        trigger the bug.
+
+                        Once the culprit font is tracked down, ``good``
+                        or ``bad`` will have no effect anymore. ``run``
+                        will always end up processing the single font
+                        file that was left.
+                        Use ``--bisect=stop`` to clear the bisection
+                        state.
+
+miscellaneous
+-----------------------------------------------------------------------
+--verbose=N, -v         Set verbosity level to *n* or the number of
+                        repetitions of ``-v``.
+--quiet                 No verbose output (log level set to zero).
+--log=CHANNEL           Redirect log output (for database
+                        troubleshooting), where *CHANNEL* can be
+
+                        1) ``stdout`` -> all output will be
+                           dumped to the terminal (default); or
+                        2) ``file`` -> write to a file to the temporary
+                           directory (the name will be chosen
+                           automatically.
+
+--version, -V           Show version numbers of components as well as
+                        some basic information and exit.
+--help, -h              Show help message and exit.
+
+--diagnose=CHECK        Run the diagnostic procedure *CHECK*. Available
+                        procedures are:
+
+                        1) ``files`` -> check *Luaotfload* files for
+                           modifications;
+                        2) ``permissions`` -> check permissions of
+                           cache directories and files;
+                        3) ``environment`` -> print relevant
+                            environment and kpse variables;
+                        4) ``repository`` -> check the git repository
+                           for new releases,
+                        5) ``index`` -> check database, display
+                           information about it.
+
+                        Procedures can be chained by concatenating with
+                        commas, e.g. ``--diagnose=files,permissions``.
+                        Specify ``thorough`` to run all checks.
+
+--conf=FILE             Read the configuration from *FILE*. See
+                        **luaotfload.conf**\(%) for documentation
+                        concerning the format and available options.
+--dumpconf              Print the currently active configuration; the
+                        output can be saved to a file and used for
+                        bootstrapping a custom configuration files.
+
+FILES
+=======================================================================
+
+The font name database is usually located in the directory
+``texmf-var/luatex-cache/generic/names/`` (``$TEXMFCACHE`` as set in
+``texmf.cnf``) of your *TeX Live* distribution as a zlib-compressed
+file ``luaotfload-names.lua.gz``.
+The experimental lookup cache will be created as
+``luaotfload-lookup-cache.lua`` in the same directory.
+These Lua tables are not used directly by Luaotfload, though.
+Instead, they are compiled to Lua bytecode which is written to
+corresponding files with the extension ``.luc`` in the same directory.
+When modifying the files by hand keep in mind that only if the bytecode
+files are missing will Luaotfload use the plain version instead.
+Both kinds of files are safe to delete, at the cost of regenerating
+them with the next run of *LuaTeX*.
+
+SEE ALSO
+=======================================================================
+
+**luaotfload.conf**\(5), **luatex**\(1), **lua**\(1)
+
+* ``texdoc luaotfload`` to display the manual for the *Luaotfload*
+  package
+* Luaotfload development `<https://github.com/lualatex/luaotfload>`_
+* LuaLaTeX mailing list  `<http://tug.org/pipermail/lualatex-dev/>`_
+* LuaTeX                 `<http://luatex.org/>`_
+* ConTeXt                `<http://wiki.contextgarden.net>`_
+* Luaotfload on CTAN     `<http://ctan.org/pkg/luaotfload>`_
+
+BUGS
+=======================================================================
+
+Tons, probably.
+
+AUTHORS
+=======================================================================
+
+*Luaotfload* was developed by the LuaLaTeX dev team
+(`<https://github.com/lualatex/>`__). It is currently maintained by Ulrike Fischer
+and Marcel Krüger at `<https://github.com/u-fischer/luaotfload>`__
+The fontloader code is provided by Hans Hagen of Pragma ADE, Hasselt
+NL (`<http://pragma-ade.com/>`__).
+
+This manual page was written by Philipp Gesang <phg at phi-gamma.net>.
+

Added: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.tex	2018-09-26 20:50:34 UTC (rev 48771)
@@ -0,0 +1,517 @@
+\documentclass[a4paper]{article}
+% generated by Docutils <http://docutils.sourceforge.net/>
+% rubber: set program xelatex
+\usepackage{fontspec}
+% \defaultfontfeatures{Scale=MatchLowercase}
+% straight double quotes (defined T1 but missing in TU):
+\ifdefined \UnicodeEncodingName
+  \DeclareTextCommand{\textquotedbl}{\UnicodeEncodingName}{%
+    {\addfontfeatures{RawFeature=-tlig,Mapping=}\char34}}%
+\fi
+\usepackage{ifthen}
+\usepackage{alltt}
+\setcounter{secnumdepth}{0}
+\usepackage{tabularx}
+
+%%% Custom LaTeX preamble
+% Linux Libertine (free, wide coverage, not only for Linux)
+\setmainfont{Linux Libertine O}
+\setsansfont{Linux Biolinum O}
+\setmonofont[HyphenChar=None,Scale=MatchLowercase]{DejaVu Sans Mono}
+
+%%% User specified packages and stylesheets
+
+%%% Fallback definitions for Docutils-specific commands
+
+% providelength (provide a length variable and set default, if it is new)
+\providecommand*{\DUprovidelength}[2]{
+  \ifthenelse{\isundefined{#1}}{\newlength{#1}\setlength{#1}{#2}}{}
+}
+
+% docinfo (width of docinfo table)
+\DUprovidelength{\DUdocinfowidth}{0.9\linewidth}
+
+% subtitle (in document title)
+\providecommand*{\DUdocumentsubtitle}[1]{{\large #1}}
+
+% optionlist environment
+\providecommand*{\DUoptionlistlabel}[1]{\bf #1 \hfill}
+\DUprovidelength{\DUoptionlistindent}{3cm}
+\ifthenelse{\isundefined{\DUoptionlist}}{
+  \newenvironment{DUoptionlist}{%
+    \list{}{\setlength{\labelwidth}{\DUoptionlistindent}
+            \setlength{\rightmargin}{1cm}
+            \setlength{\leftmargin}{\rightmargin}
+            \addtolength{\leftmargin}{\labelwidth}
+            \addtolength{\leftmargin}{\labelsep}
+            \renewcommand{\makelabel}{\DUoptionlistlabel}}
+  }
+  {\endlist}
+}{}
+% hyperlinks:
+\ifthenelse{\isundefined{\hypersetup}}{
+  \usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
+  \usepackage{bookmark}
+  \urlstyle{same} % normal text font (alternatives: tt, rm, sf)
+}{}
+\hypersetup{
+  pdftitle={luaotfload-tool},
+}
+
+\title{luaotfload-tool%
+  \label{luaotfload-tool}%
+  \\ % subtitle%
+  \DUdocumentsubtitle{generate and query the Luaotfload font names database}%
+  \label{generate-and-query-the-luaotfload-font-names-database}}
+\author{}
+\date{}
+
+%%% Body
+\begin{document}
+\maketitle
+
+% Docinfo
+\begin{center}
+\begin{tabularx}{\DUdocinfowidth}{lX}
+\textbf{Date}: &
+	2018-09-21 \\
+\textbf{Copyright}: &
+	GPL v2.0 \\
+\textbf{Version}: &
+	2.9 \\
+\textbf{Manual section}: &
+1
+\\
+\textbf{Manual group}: &
+text processing
+\\
+\end{tabularx}
+\end{center}
+
+
+\section{SYNOPSIS%
+  \label{synopsis}%
+}
+
+\textbf{luaotfload-tool} {[} -bcDfFiIlLnpqRSuvVhw {]}
+
+\begin{description}
+\item[{\textbf{luaotfload-tool} --update {[} --force {]} {[} --quiet {]} {[} --verbose {]}}] \leavevmode 
+{[} --prefer-texmf {]} {[} --dry-run {]}
+{[} --formats={[}+|-{]}EXTENSIONS {]}
+{[} --no-compress {]} {[} --no-strip {]}
+{[} --local {]} {[} --max-fonts=N {]}
+
+\item[{\textbf{luaotfload-tool} --find=FONTNAME {[} --fuzzy {]} {[} --info {]} {[} --inspect {]}}] \leavevmode 
+{[} --no-reload {]}
+
+\end{description}
+
+\textbf{luaotfload-tool} --flush-lookups
+
+\textbf{luaotfload-tool} --cache=DIRECTIVE
+
+\textbf{luaotfload-tool} --list=CRITERION{[}:VALUE{]} {[} --fields=F1,F2,...,Fn {]}
+
+\textbf{luaotfload-tool} --bisect=DIRECTIVE
+
+\textbf{luaotfload-tool} --help
+
+\textbf{luaotfload-tool} --version
+
+\textbf{luaotfload-tool} --show-blacklist
+
+\textbf{luaotfload-tool} --diagnose=CHECK
+
+\textbf{luaotfload-tool} --conf=FILE --dumpconf
+
+
+\section{DESCRIPTION%
+  \label{description}%
+}
+
+luaotfload-tool accesses the font names database that is required by
+the \emph{Luaotfload} package. There are two general modes: \textbf{update} and
+\textbf{query}.
+
+\begin{itemize}
+\item \textbf{update}:  update the database or rebuild it entirely;
+
+\item \textbf{query}:   resolve a font name or display close matches.
+\end{itemize}
+
+
+\section{OPTIONS%
+  \label{options}%
+}
+
+
+\subsection{update mode%
+  \label{update-mode}%
+}
+
+\begin{DUoptionlist}
+\item[--update, -u]  Update the database; indexes new fonts.
+
+\item[--force, -f]  Force rebuilding of the database; re-indexes
+all fonts.
+
+\item[--local, -L]  Include font files in \texttt{\$PWD}. This option
+will cause large parts of the database to be
+rebuilt. Thus it is quite inefficient.
+Additionally, if local font files are found,
+the database is prevented from being saved
+to disk, so the local fonts need to be parsed
+with every invocation of \texttt{luaotfload-tool}.
+
+\item[--no-reload, -n]  Suppress auto-updates to the database (e.g.
+when \texttt{--find} is passed an unknown name).
+
+\item[--no-compress, -c]  Do not filter the plain text version of the
+font index through gzip. Useful for debugging
+if your editor is built without zlib.
+
+\item[--prefer-texmf, -p]  Organize the file name database in a way so
+that it prefer fonts in the \emph{TEXMF} tree over
+system fonts if they are installed in both.
+
+\item[--formats=EXTENSIONS]  Extensions of the font files to index.
+Where \emph{EXTENSIONS} is a comma-separated list of
+supported file extensions (otf, ttf, ttc).
+If the list is prefixed
+with a \texttt{+} sign, the given list is added to
+the currently active one; \texttt{-} subtracts.
+Default: \emph{otf,ttf,ttc}.
+Examples:
+
+\begin{enumerate}
+\renewcommand{\labelenumi}{\arabic{enumi})}
+\item \texttt{--formats=-ttc,ttf} would skip
+TrueType fonts and font collections;
+
+\item \texttt{--formats=otf} would scan only OpenType
+files;
+
+\item \texttt{--formats=+afm} includes binary
+Postscript files accompanied by an AFM file.
+\end{enumerate}
+\end{DUoptionlist}
+
+
+\subsection{query mode%
+  \label{query-mode}%
+}
+
+\begin{DUoptionlist}
+\item[--find=NAME]  Resolve a font name; this looks up <name> in
+the database and prints the file name it is
+mapped to.
+\texttt{--find} also understands request syntax,
+i.e. \texttt{--find=file:foo.otf} checks whether
+\texttt{foo.otf} is indexed.
+
+\item[--fuzzy, -F]  Show approximate matches to the file name if
+the lookup was unsuccessful (requires
+\texttt{--find}).
+
+\item[--info, -i]  Display basic information to a resolved font
+file (requires \texttt{--find}).
+
+\item[--inspect, -I]  Display detailed information by loading the
+font and analyzing the font table; very slow!
+For the meaning of the returned fields see
+the LuaTeX documentation.
+(requires \texttt{--find}).
+
+\item[--list=CRITERION]  Show entries, where \emph{CRITERION} is one of the
+following:
+
+\begin{enumerate}
+\renewcommand{\labelenumi}{\arabic{enumi})}
+\item the character \texttt{*}, selecting all entries;
+
+\item a field of a database entry, for instance
+\emph{version} or \emph{format*}, according to which
+the output will be sorted.
+Information in an unstripped database (see
+the option \texttt{--no-strip} above) is nested:
+Subfields of a record can be addressed using
+the \texttt{->} separator, e. g.
+\texttt{file->location}, \texttt{style->units\_per\_em},
+or
+\texttt{names->sanitized->english->prefmodifiers}.
+NB: shell syntax requires that arguments
+containing \texttt{->} be properly quoted!
+
+\item an expression of the form \texttt{field:value} to
+limit the output to entries whose \texttt{field}
+matches \texttt{value}.
+\end{enumerate}
+
+For example, in order to output file names and
+corresponding versions, sorted by the font
+format:
+
+\begin{quote}
+\begin{alltt}
+./luaotfload-tool.lua --list="format" --fields="file->base,version"
+\end{alltt}
+\end{quote}
+
+This prints:
+
+\begin{quote}
+\begin{alltt}
+otf latinmodern-math.otf  Version 1.958
+otf lmromancaps10-oblique.otf 2.004
+otf lmmono8-regular.otf 2.004
+otf lmmonoproplt10-bold.otf 2.004
+otf lmsans10-oblique.otf  2.004
+otf lmromanslant8-regular.otf 2.004
+otf lmroman12-italic.otf  2.004
+otf lmsansdemicond10-oblique.otf  2.004
+...
+\end{alltt}
+\end{quote}
+
+\item[--fields=FIELDS]  Comma-separated list of fields that should be
+printed.
+Information in an unstripped database (see the
+option \texttt{--no-strip} above) is nested:
+Subfields of a record can be addressed using
+the \texttt{->} separator, e. g.
+\texttt{file->location}, \texttt{style->units\_per\_em},
+or \texttt{names->sanitized->english->subfamily}.
+The default is plainname,version*.
+(Only meaningful with \texttt{--list}.)
+\end{DUoptionlist}
+
+
+\subsection{font and lookup caches%
+  \label{font-and-lookup-caches}%
+}
+
+\begin{DUoptionlist}
+\item[--flush-lookups]  Clear font name lookup cache (experimental).
+
+\item[--cache=DIRECTIVE]  Cache control, where \emph{DIRECTIVE} is one of the
+following:
+
+\begin{enumerate}
+\renewcommand{\labelenumi}{\arabic{enumi})}
+\item \texttt{purge} -> delete Lua files from cache;
+
+\item \texttt{erase} -> delete Lua and Luc files from
+cache;
+
+\item \texttt{show}  -> print stats.
+\end{enumerate}
+\end{DUoptionlist}
+
+
+\subsection{debugging methods%
+  \label{debugging-methods}%
+}
+
+\begin{DUoptionlist}
+\item[--show-blacklist, -b]  Show blacklisted files (not directories).
+
+\item[--dry-run, -D]  Don’t load fonts when updating the database;
+scan directories only.
+(For debugging file system related issues.)
+
+\item[--no-strip]  Do not strip redundant information after
+building the database. Warning: this will
+inflate the index to about two to three times
+the normal size.
+
+\item[--max-fonts=N]  Process at most \emph{N} font files, including fonts
+already indexed in the count.
+
+\item[--bisect=DIRECTIVE]  Bisection of the font database.
+This mode is intended as assistance in
+debugging the Luatex engine, especially when
+tracking memleaks or buggy fonts.
+
+\emph{DIRECTIVE} can be one of the following:
+
+\begin{enumerate}
+\renewcommand{\labelenumi}{\arabic{enumi})}
+\item \texttt{run} -> Make \texttt{luaotfload-tool} respect
+the bisection progress when running.
+Combined with \texttt{--update} and possibly
+\texttt{--force} this will only process the files
+from the start up until the pivot and ignore
+the rest.
+
+\item \texttt{start} -> Start bisection: create a
+bisection state file and initialize the low,
+high, and pivot indices.
+
+\item \texttt{stop} -> Terminate the current bisection
+session by deleting the state file.
+
+\item \texttt{good} | \texttt{bad} -> Mark the section
+processed last as “good” or “bad”,
+respectively. The next bisection step will
+continue with the bad section.
+
+\item \texttt{status} -> Print status information about
+the current bisection session. Hint: Use
+with higher verbosity settings for more
+output.
+\end{enumerate}
+
+A bisection session is initiated by issuing the
+\texttt{start} directive. This sets the pivot to the
+middle of the list of available font files.
+Now run \emph{luaotfload-tool} with the \texttt{--update}
+flag set as well as \texttt{--bisect=run}: only the
+fonts up to the pivot will be considered. If
+that task exhibited the issue you are tracking,
+then tell Luaotfload using \texttt{--bisect=bad}.
+The next step of \texttt{--bisect=run} will continue
+bisection with the part of the files below the
+pivot.
+Likewise, issue \texttt{--bisect=good} in order to
+continue with the fonts above the pivot,
+assuming the tested part of the list did not
+trigger the bug.
+
+Once the culprit font is tracked down, \texttt{good}
+or \texttt{bad} will have no effect anymore. \texttt{run}
+will always end up processing the single font
+file that was left.
+Use \texttt{--bisect=stop} to clear the bisection
+state.
+\end{DUoptionlist}
+
+
+\subsection{miscellaneous%
+  \label{miscellaneous}%
+}
+
+\begin{DUoptionlist}
+\item[--verbose=N, -v]  Set verbosity level to \emph{n} or the number of
+repetitions of \texttt{-v}.
+
+\item[--quiet]  No verbose output (log level set to zero).
+
+\item[--log=CHANNEL]  Redirect log output (for database
+troubleshooting), where \emph{CHANNEL} can be
+
+\begin{enumerate}
+\renewcommand{\labelenumi}{\arabic{enumi})}
+\item \texttt{stdout} -> all output will be
+dumped to the terminal (default); or
+
+\item \texttt{file} -> write to a file to the temporary
+directory (the name will be chosen
+automatically.
+\end{enumerate}
+
+\item[--version, -V]  Show version numbers of components as well as
+some basic information and exit.
+
+\item[--help, -h]  Show help message and exit.
+
+\item[--diagnose=CHECK]  Run the diagnostic procedure \emph{CHECK}. Available
+procedures are:
+
+\begin{enumerate}
+\renewcommand{\labelenumi}{\arabic{enumi})}
+\item \texttt{files} -> check \emph{Luaotfload} files for
+modifications;
+
+\item \texttt{permissions} -> check permissions of
+cache directories and files;
+
+\item 
+\begin{description}
+\item[{\texttt{environment} -> print relevant}] \leavevmode 
+environment and kpse variables;
+
+\end{description}
+
+\item \texttt{repository} -> check the git repository
+for new releases,
+
+\item \texttt{index} -> check database, display
+information about it.
+\end{enumerate}
+
+Procedures can be chained by concatenating with
+commas, e.g. \texttt{--diagnose=files,permissions}.
+Specify \texttt{thorough} to run all checks.
+
+\item[--conf=FILE]  Read the configuration from \emph{FILE}. See
+\textbf{luaotfload.conf}(\%) for documentation
+concerning the format and available options.
+
+\item[--dumpconf]  Print the currently active configuration; the
+output can be saved to a file and used for
+bootstrapping a custom configuration files.
+\end{DUoptionlist}
+
+
+\section{FILES%
+  \label{files}%
+}
+
+The font name database is usually located in the directory
+\texttt{texmf-var/luatex-cache/generic/names/} (\texttt{\$TEXMFCACHE} as set in
+\texttt{texmf.cnf}) of your \emph{TeX Live} distribution as a zlib-compressed
+file \texttt{luaotfload-names.lua.gz}.
+The experimental lookup cache will be created as
+\texttt{luaotfload-lookup-cache.lua} in the same directory.
+These Lua tables are not used directly by Luaotfload, though.
+Instead, they are compiled to Lua bytecode which is written to
+corresponding files with the extension \texttt{.luc} in the same directory.
+When modifying the files by hand keep in mind that only if the bytecode
+files are missing will Luaotfload use the plain version instead.
+Both kinds of files are safe to delete, at the cost of regenerating
+them with the next run of \emph{LuaTeX}.
+
+
+\section{SEE ALSO%
+  \label{see-also}%
+}
+
+\textbf{luaotfload.conf}(5), \textbf{luatex}(1), \textbf{lua}(1)
+
+\begin{itemize}
+\item \texttt{texdoc luaotfload} to display the manual for the \emph{Luaotfload}
+package
+
+\item Luaotfload development \url{https://github.com/lualatex/luaotfload}
+
+\item LuaLaTeX mailing list  \url{http://tug.org/pipermail/lualatex-dev/}
+
+\item LuaTeX                 \url{http://luatex.org/}
+
+\item ConTeXt                \url{http://wiki.contextgarden.net}
+
+\item Luaotfload on CTAN     \url{http://ctan.org/pkg/luaotfload}
+\end{itemize}
+
+
+\section{BUGS%
+  \label{bugs}%
+}
+
+Tons, probably.
+
+
+\section{AUTHORS%
+  \label{authors}%
+}
+
+\emph{Luaotfload} was developed by the LuaLaTeX dev team
+(\url{https://github.com/lualatex/}). It is currently maintained by Ulrike Fischer
+and Marcel Krüger at \url{https://github.com/u-fischer/luaotfload}
+The fontloader code is provided by Hans Hagen of Pragma ADE, Hasselt
+NL (\url{http://pragma-ade.com/}).
+
+This manual page was written by Philipp Gesang <\href{mailto:phg at phi-gamma.net}{phg at phi-gamma.net}>.
+
+\end{document}


Property changes on: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload-tool.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.conf.rst	2018-09-26 20:50:34 UTC (rev 48771)
@@ -0,0 +1,409 @@
+=======================================================================
+                            luaotfload.conf
+=======================================================================
+
+-----------------------------------------------------------------------
+                     Luaotfload configuration file
+-----------------------------------------------------------------------
+
+:Date:                  2018-09-21
+:Copyright:             GPL v2.0
+:Version:               2.9
+:Manual section:        5
+:Manual group:          text processing
+
+SYNOPSIS
+=======================================================================
+
+- **./luaotfload{.conf,rc}**
+- **XDG_CONFIG_HOME/luaotfload/luaotfload{.conf,rc}**
+- **~/.luaotfloadrc**
+
+DESCRIPTION
+=======================================================================
+
+The file ``luaotfload.conf`` contains configuration options for
+*Luaotfload*, a font loading and font management component for LuaTeX.
+
+
+EXAMPLE
+=======================================================================
+
+A small Luaotfload configuration file with few customizations could
+look as follows: ::
+
+    [db]
+        formats = afm,ttf
+        compress = false
+    
+    [misc]
+        termwidth = 60
+    
+    [run]
+        log-level = 6
+
+This will make Luaotfload ignore all font files except for PostScript
+binary fonts with a matching AFM file, and Truetype fonts. Also, an
+uncompressed index file will be dumped which is going to be much larger
+than the default gzip’ed index. The terminal width
+is truncated to 60 characters which influences the verbose output
+during indexing. Finally, the verbosity is increased greatly: each font
+file being processed will be printed to the stdout on a separate line,
+along with lots of other information.
+
+To observe the difference in behavior, save above snippet to
+``./luaotfload.conf`` and update the font index: ::
+
+    luaotfload-tool --update --force
+
+The current configuration can be written to disk using
+**luaotfload-tool**: ::
+
+    luaotfload-tool --dumpconf > luaotfload.conf
+
+The result can itself be used as a configuration file.
+
+
+SYNTAX
+=======================================================================
+
+The configuration file syntax follows the common INI format. For a more
+detailed description please refer to the section “CONFIGURATION FILE”
+of **git-config**\(1). A brief list of rules is given below:
+
+  * Blank lines and lines starting with a semicolon (``;``) are ignored.
+
+  * A configuration file is partitioned into sections that are declared
+    by specifying the section title in brackets on a separate line: ::
+
+        [some-section]
+        ... section content ...
+
+  * Sections consist of one or more variable assignments of the form
+    ``variable-name = value``  E. g.::
+
+        [foo]
+            bar = baz
+            quux = xyzzy
+            ...
+
+  * Section and variable names may contain only uppercase and lowercase
+    letters as well as dashes (``-``).
+
+
+VARIABLES
+=======================================================================
+
+Variables in belong into a configuration section and their values must
+be of a certain type. Some of them have further constraints. For
+example, the “color callback” must be a string of one of the values
+``post_linebreak_filter``, ``pre_linebreak_filter``, or
+``pre_output_filter``, defined in the section *run* of the
+configuration file.
+
+Currently, the configuration is organized into four sections:
+
+db
+    Options relating to the font index.
+
+misc
+    Options without a clearly defined category.
+
+paths
+    Path and file name settings.
+
+run
+    Options controlling runtime behavior of Luaotfload.
+
+The list of valid variables, the sections they are part of and their
+type is given below. Types represent Lua types that the values must be
+convertible to; they are abbreviated as follows: ``s`` for the *string*
+type, ``n`` for *number*, ``b`` for *boolean*. A value of ``nil`` means
+the variable is unset.
+
+
+Section ``db``
+-----------------------------------------------------------------------
+
++--------------------+--------+---------------------------+
+|  variable          |  type  |  default                  |
++--------------------+--------+---------------------------+
+|  compress          |   b    |  ``true``                 |
++--------------------+--------+---------------------------+
+|  designsize-dimen  |   b    |  ``bp``                   |
++--------------------+--------+---------------------------+
+|  formats           |   s    |  ``"otf,ttf,ttc"``        |
++--------------------+--------+---------------------------+
+|  max-fonts         |   n    |  ``2^51``                 |
++--------------------+--------+---------------------------+
+|  scan-local        |   b    |  ``false``                |
++--------------------+--------+---------------------------+
+|  skip-read         |   b    |  ``false``                |
++--------------------+--------+---------------------------+
+|  strip             |   b    |  ``true``                 |
++--------------------+--------+---------------------------+
+|  update-live       |   b    |  ``true``                 |
++--------------------+--------+---------------------------+
+
+The flag ``compress`` determines whether the font index (usually
+``luaotfload-names.lua[.gz]`` will be stored in compressed forms.
+If unset it is equivalent of passing ``--no-compress`` to
+**luaotfload-tool**. Since the file is only created for convenience
+and has no effect on the runtime behavior of Luaotfload, the flag
+should remain set. Most editors come with zlib support anyways.
+
+The setting ``designsize-dimen`` applies when looking up fonts from
+families with design sizes. In Opentype, these are specified as
+“decipoints” where one decipoint equals ten DTP style “big points”.
+When indexing fonts these values are converted to ``sp``. In order to
+treat the values as though they were specified in TeX points or Didot
+points, set ``designsize-dimen`` to ``pt`` or ``dd``.
+
+The list of ``formats`` must be a comma separated sequence of strings
+containing one or more of these elements:
+
+* ``otf``               (OpenType format),
+* ``ttf`` and ``ttc``       (TrueType format),
+* ``afm``               (Adobe Font Metrics),
+
+It corresponds loosely to the ``--formats`` option to
+**luaotfload-tool**. Invalid or duplicate members are ignored; if the
+list does not contain any useful identifiers, the default list
+``"otf,ttf,ttc"`` will be used.
+
+The variable ``max-fonts`` determines after processing how many font
+files the font scanner will terminate the search. This is useful for
+debugging issues with the font index and has the same effect as the
+option ``--max-fonts`` to **luaotfload-tools**.
+
+The ``scan-local`` flag, if set, will incorporate the current working
+directory as a font search location. NB: This will potentially slow
+down document processing because a font index with local fonts will not
+be saved to disk, so these fonts will have to be re-indexed whenever
+the document is built.
+
+The ``skip-read`` flag is only useful for debugging: It makes
+Luaotfload skip reading fonts. The font information for rebuilding the
+index is taken from the presently existing one.
+
+Unsetting the ``strip`` flag prevents Luaotfload from removing data
+from the index that is only useful when processing font files. NB: this
+can increase the size of the index files significantly and has no
+effect on the runtime behavior.
+
+If ``update-live`` is set, Luaotfload will reload the database if it
+cannot find a requested font. Those who prefer to update manually using
+**luaotfload-tool** should unset this flag. This option does not affect
+rebuilds due to version mismatch.
+
+Section ``default-features``
+-----------------------------------------------------------------------
+
+By default Luaotfload enables ``node`` mode and picks the default font
+features that are prescribed in the OpenType standard. This behavior
+may be overridden in the ``default-features`` section. Global defaults
+that will be applied for all scripts can be set via the ``global``
+option, others by the script they are to be applied to. For example,
+a setting of ::
+
+  [default-features]
+      global = mode=base,color=0000FF
+      dflt   = smcp,onum
+
+would force *base* mode, tint all fonts blue and activate small
+capitals and text figures globally. Features are specified as a comma
+separated list of variables or variable-value pairs. Variables without
+an explicit value are set to ``true``.
+
+
+Section ``misc``
+-----------------------------------------------------------------------
+
++---------------+--------+-------------------------+
+|  variable     |  type  |  default                |
++---------------+--------+-------------------------+
+|  statistics   |   b    |  ``false``              |
++---------------+--------+-------------------------+
+|  termwidth    |   n    |  ``nil``                |
++---------------+--------+-------------------------+
+|  version      |   s    |  <Luaotfload version>   |
++---------------+--------+-------------------------+
+
+With ``statistics`` enabled, extra statistics will be collected during
+index creation and appended to the index file. It may then be queried
+at the Lua end or inspected by reading the file itself.
+
+The value of ``termwidth``, if set, overrides the value retrieved by
+querying the properties of the terminal in which Luatex runs. This is
+useful if the engine runs with ``shell_escape`` disabled and the actual
+terminal dimensions cannot be retrieved.
+
+The value of ``version`` is derived from the version string hard-coded
+in the Luaotfload source. Override at your own risk.
+
+
+Section ``paths``
+-----------------------------------------------------------------------
+
++------------------+--------+------------------------------------+
+|  variable        |  type  |  default                           |
++------------------+--------+------------------------------------+
+|  cache-dir       |   s    |  ``"fonts"``                       |
++------------------+--------+------------------------------------+
+|  names-dir       |   s    |  ``"names"``                       |
++------------------+--------+------------------------------------+
+|  index-file      |   s    |  ``"luaotfload-names.lua"``        |
++------------------+--------+------------------------------------+
+|  lookups-file    |   s    |  ``"luaotfload-lookup-cache.lua"`` |
++------------------+--------+------------------------------------+
+
+The paths ``cache-dir`` and ``names-dir`` determine the subdirectory
+inside the Luaotfload subtree of the ``luatex-cache`` directory where
+the font cache and the font index will be stored, respectively.
+
+Inside the index directory, the names of the index file and the font
+lookup cache will be derived from the respective values of
+``index-file`` and ``lookups-file``. This is the filename base for the
+bytecode compiled version as well as -- for the index -- the gzipped
+version.
+
+
+Section ``run``
+-----------------------------------------------------------------------
+
++------------------+--------+------------------------------+
+|  variable        |  type  |  default                     |
++------------------+--------+------------------------------+
+|  anon-sequence   |   s    |  ``"tex,path,name"``         |
++------------------+--------+------------------------------+
+|  color-callback  |   s    |  ``"post_linebreak_filter"`` |
++------------------+--------+------------------------------+
+|  definer         |   s    |  ``"patch"``                 |
++------------------+--------+------------------------------+
+|  log-level       |   n    |  ``0``                       |
++------------------+--------+------------------------------+
+|  resolver        |   s    |  ``"cached"``                |
++------------------+--------+------------------------------+
+|  fontloader      |   s    |  ``"default"``               |
++------------------+--------+------------------------------+
+
+Unqualified font lookups are treated with the flexible “anonymous”
+mechanism. This involves a chain of lookups applied successively until
+the first one yields a match. By default, the lookup will first search
+for TFM fonts using the Kpathsea library. If this wasn’t successful, an
+attempt is made at interpreting the request as an absolute path (like
+the ``[/path/to/font/foo.ttf]`` syntax) or a file name
+(``file:foo.ttf``). Finally, the request is interpreted as a font name
+and retrieved from the index (``name:Foo Regular``). This behavior can
+be configured by specifying a list as the value to ``anon-sequence``.
+Available items are ``tex``, ``path``, ``name`` -- representing the
+lookups described above, respectively --, and ``file`` for searching a
+filename but not an absolute path. Also, ``my`` lookups are valid
+values but they should only be used from within TeX documents, because
+there is no means of customizing a ``my`` lookups on the command line.
+
+The ``color-callback`` option determines the stage at which fonts that
+defined with a ``color=xxyyzz`` feature will be colorized. By default
+this happens in a ``post_linebreak_filter`` but alternatively the
+``pre_linebreak_filter`` or ``pre_output_filter`` may be chosen, which
+is faster but might produce inconsistent output. The
+``pre_output_filter`` used to be the default in the 1.x series of
+Luaotfload, whilst later versions up to and including 2.5 hooked into
+the ``pre_linebreak_filter`` which naturally didn’t affect any glyphs
+inserting during hyphenation. Both are kept around as options to
+restore the previous behavior if necessary.
+
+The ``definer`` allows for switching the ``define_font`` callback.
+Apart from the default ``patch`` one may also choose the ``generic``
+one that comes with the vanilla fontloader. Beware that this might
+break tools like Fontspec that rely on the ``patch_font`` callback
+provided by Luaotfload to perform important corrections on font data.
+
+The fontloader backend can be selected by setting the value of
+``fontloader``. The most important choices are ``default``, which will
+load the dedicated Luaotfload fontloader, and ``reference``, the
+upstream package as shipped with Luaotfload. Other than those, a file
+name accessible via kpathsea can be specified.
+
+Alternatively, the individual files that constitute the fontloader can
+be loaded directly. While less efficient, this greatly aids debugging
+since error messages will reference the actual line numbers of the
+source files and explanatory comments are not stripped. Currently,
+three distinct loading strategies are available: ``unpackaged`` will
+load the batch that is part of Luaotfload. These contain the identical
+source code that the reference fontloader has been compiled from.
+Another option, ``context`` will attempt to load the same files by
+their names in the Context format from the search path. Consequently
+this option allows to use the version of Context that comes with the
+TeX distribution. Distros tend to prefer the stable version (“current”
+in Context jargon) of those files so certain bugs encountered in the
+more bleeding edge Luaotfload can be avoided this way. A third option
+is to use ``context`` with a colon to specify a directory prefix where
+the *TEXMF* is located that the files should be loaded from, e. g.
+``context:~/context/tex/texmf-context``. This can be used when
+referencing another distribution like the Context minimals that is
+installed under a different path not indexed by kpathsea.
+
+The value of ``log-level`` sets the default verbosity of messages
+printed by Luaotfload. Only messages defined with a verbosity of less
+than or equal to the supplied value will be output on the terminal.
+At a log level of five Luaotfload can be very noisy. Also, printing too
+many messages will slow down the interpreter due to line buffering
+being disabled (see **setbuf**\(3)).
+
+The ``resolver`` setting allows choosing the font name resolution
+function: With the default value ``cached`` Luaotfload saves the result
+of a successful font name request to a cache file to speed up
+subsequent lookups. The alternative, ``normal`` circumvents the cache
+and resolves every request individually. (Since to the restructuring of
+the font name index in Luaotfload 2.4 the performance difference
+between the cached and uncached lookups should be marginal.)
+
+
+FILES
+=======================================================================
+
+Luaotfload only processes the first configuration file it encounters at
+one of the search locations. The file name may be either
+``luaotfload.conf`` or ``luaotfloadrc``, except for the dotfile in the
+user’s home directory which is expected at ``~/.luaotfloadrc``.
+
+Configuration files are located following a series of steps. The search
+terminates as soon as a suitable file is encountered. The sequence of
+locations that Luaotfload looks at is
+
+i.    The current working directory of the LuaTeX process.
+ii.   The subdirectory ``luaotfload/`` inside the XDG configuration
+      tree, e. g. ``/home/oenothea/config/luaotfload/``.
+iii.  The dotfile.
+iv.   The *TEXMF* (using kpathsea).
+
+
+SEE ALSO
+=======================================================================
+
+**luaotfload-tool**\(1), **luatex**\(1), **lua**\(1)
+
+* ``texdoc luaotfload`` to display the PDF manual for the *Luaotfload*
+  package
+* Luaotfload development `<https://github.com/u-fischer/luaotfload>`_
+* LuaLaTeX mailing list  `<http://tug.org/pipermail/lualatex-dev/>`_
+* LuaTeX                 `<http://luatex.org/>`_
+* Luaotfload on CTAN     `<http://ctan.org/pkg/luaotfload>`_
+
+
+REFERENCES
+=======================================================================
+
+* The XDG base specification
+  `<http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_.
+
+AUTHORS
+=======================================================================
+
+*Luaotfload* was developed by the LuaLaTeX dev team
+(`<https://github.com/lualatex/>`_). It is currently maintained by Ulrike Fischer
+and Marcel Krüger at `<https://github.com/u-fischer/luaotfload>`_
+
+This manual page was written by Philipp Gesang <phg at phi-gamma.net>.
+

Deleted: trunk/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.pdf
===================================================================
(Binary files differ)

Deleted: trunk/Master/texmf-dist/doc/luatex/luaotfload/valgrind-kpse-suppression.sup
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luaotfload/valgrind-kpse-suppression.sup	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/doc/luatex/luaotfload/valgrind-kpse-suppression.sup	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,140 +0,0 @@
-{
-   kpathsea-garbage-1
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:kpathsea_cnf_get
-}
-
-{
-   kpathsea-garbage-2
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:kpse_program_basename
-}
-
-
-{
-   kpathsea-garbage-3
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:kpse_find_file
-}
-
-
-{
-   kpathsea-garbage-4
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:find_file
-}
-
-{
-   kpathsea-garbage-5
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:lua_kpse_lookup
-}
-
-{
-   kpathsea-garbage-6
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:find_file
-}
-
-
-{
-   kpathsea-garbage-7
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:expand_path
-}
-
-{
-   kpathsea-garbage-8
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:do_lua_kpathsea_lookup
-}
-
-
-{
-   kpathsea-garbage-9
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:kpathsea_find_file
-}
-
-
-{
-   kpathsea-garbage-10
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:kpathsea_init_db
-}
-
-
-{
-   kpathsea-garbage-11
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:kpathsea_find_file_generic
-}
-
-
-{
-   kpathsea-garbage-12
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:expand_var
-}
-
-
-{
-   kpathsea-garbage-13
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:init_path
-}
-
-
-{
-   kpathsea-garbage-14
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:kpse_in_name_ok
-}
-
-
-{
-   kpathsea-garbage-15
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:kpathsea_var_value
-}
-
-
-{
-   kpathsea-garbage-16
-   Memcheck:Leak
-   match-leak-kinds: all
-   ...
-   fun:kpse_set_program_name
-}
-
-

Modified: trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.1	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.1	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH LUAOTFLOAD-TOOL 1 "2017-01-28" "2.8" "text processing"
+.TH LUAOTFLOAD-TOOL 1 "2018-09-21" "2.9" "text processing"
 .SH NAME
 luaotfload-tool \- generate and query the Luaotfload font names database
 .
@@ -429,8 +429,9 @@
 Tons, probably.
 .SH AUTHORS
 .sp
-\fILuaotfload\fP is maintained by the LuaLaTeX dev team
-(\fI\%https://github.com/lualatex/\fP).
+\fILuaotfload\fP was developed by the LuaLaTeX dev team
+(\fI\%https://github.com/lualatex/\fP). It is currently maintained by Ulrike Fischer
+and Marcel Krüger at \fI\%https://github.com/u\-fischer/luaotfload\fP
 The fontloader code is provided by Hans Hagen of Pragma ADE, Hasselt
 NL (\fI\%http://pragma\-ade.com/\fP).
 .sp

Modified: trunk/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.5
===================================================================
--- trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.5	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.5	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH LUAOTFLOAD.CONF 5 "2017-01-29" "2.8" "text processing"
+.TH LUAOTFLOAD.CONF 5 "2018-09-21" "2.9" "text processing"
 .SH NAME
 luaotfload.conf \- Luaotfload configuration file
 .
@@ -265,8 +265,11 @@
 should remain set. Most editors come with zlib support anyways.
 .sp
 The setting \fBdesignsize\-dimen\fP applies when looking up fonts from
-families with design sizes. The default of DTP\-style “big points”
-can be changed for \fBpt\fP or even \fBdd\fP\&.
+families with design sizes. In Opentype, these are specified as
+“decipoints” where one decipoint equals ten DTP style “big points”.
+When indexing fonts these values are converted to \fBsp\fP\&. In order to
+treat the values as though they were specified in TeX points or Didot
+points, set \fBdesignsize\-dimen\fP to \fBpt\fP or \fBdd\fP\&.
 .sp
 The list of \fBformats\fP must be a comma separated sequence of strings
 containing one or more of these elements:
@@ -602,7 +605,7 @@
 \fBtexdoc luaotfload\fP to display the PDF manual for the \fILuaotfload\fP
 package
 .IP \(bu 2
-Luaotfload development \fI\%https://github.com/lualatex/luaotfload\fP
+Luaotfload development \fI\%https://github.com/u\-fischer/luaotfload\fP
 .IP \(bu 2
 LuaLaTeX mailing list  \fI\%http://tug.org/pipermail/lualatex\-dev/\fP
 .IP \(bu 2
@@ -618,8 +621,9 @@
 .UNINDENT
 .SH AUTHORS
 .sp
-\fILuaotfload\fP is maintained by the LuaLaTeX dev team
-(\fI\%https://github.com/lualatex/\fP).
+\fILuaotfload\fP was developed by the LuaLaTeX dev team
+(\fI\%https://github.com/lualatex/\fP). It is currently maintained by Ulrike Fischer
+and Marcel Krüger at \fI\%https://github.com/u\-fischer/luaotfload\fP
 .sp
 This manual page was written by Philipp Gesang <\fI\%phg at phi\-gamma.net\fP>.
 .SH COPYRIGHT

Modified: trunk/Master/texmf-dist/doc/man/man5/luaotfload.conf.man5.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/scripts/luaotfload/luaotfload-tool.lua	2018-09-26 20:50:34 UTC (rev 48771)
@@ -2,13 +2,13 @@
 -----------------------------------------------------------------------
 --         FILE:  luaotfload-tool.lua
 --  DESCRIPTION:  database functionality
--- REQUIREMENTS:  luaotfload 2.8
+-- REQUIREMENTS:  luaotfload 2.9
 --       AUTHOR:  Khaled Hosny, Élie Roux, Philipp Gesang
 --      LICENSE:  GPL v2.0
 -----------------------------------------------------------------------
 
 luaotfload                     = luaotfload or { }
-local version                  = "2.8"
+local version                  = "2.9"
 luaotfload.version             = version
 luaotfload.min_luatex_version  = { 0, 95, 0 }
 luaotfload.self                = "luaotfload-tool"

Deleted: trunk/Master/texmf-dist/scripts/luaotfload/mkcharacters
===================================================================
--- trunk/Master/texmf-dist/scripts/luaotfload/mkcharacters	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/scripts/luaotfload/mkcharacters	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,226 +0,0 @@
-#!/usr/bin/env texlua
------------------------------------------------------------------------
---         FILE:  mkcharacters.lua
---        USAGE:  ./mkcharacters.lua 
---  DESCRIPTION:  import parts of char-def.lua
--- REQUIREMENTS:  lua, ConTeXt, the lualibs package
---       AUTHOR:  Philipp Gesang (Phg), <phg at phi-gamma.net>
------------------------------------------------------------------------
--- We create a stripped-down version of char-def.lua, suitable for use
--- with the generic font loader.
------------------------------------------------------------------------
-
------------------------------------------------------------------------
---                              config
------------------------------------------------------------------------
-local mkivpath      = arg[1]
-local charfile      = arg[2] or "./build/luaotfload-characters.lua"
-
----  for every code point char-def.lua provides a set of fields. they
----  are:
----
----     * adobename
----     * category
----     * cjkwd
----     * comment
----     * contextname
----     * description
----     * direction
----     * lccode
----     * linebreak
----     * mathclass
----     * mathextensible
----     * mathfiller
----     * mathname
----     * mathspec
----     * mathstretch
----     * mathsymbol
----     * mirror
----     * shcode
----     * specials
----     * textclass
----     * uccode
----     * unicodeslot
----     * variants
-
-local import = {
-  "direction", "mirror", --> πολυγλωσσία/uax9
-  "category",            --> https://gist.github.com/phi-gamma/5812290
-  "textclass",           --> https://gist.github.com/phi-gamma/6488187 
-}
-
------------------------------------------------------------------------
---                             includes
------------------------------------------------------------------------
-
-kpse.set_program_name"luatex"
-
-require "lualibs"
-
-local chardef
-local charini
-
-if not mkivpath then
-  mkivpath = assert (kpse.expand_path
-                      "~/context/tex/texmf-context/tex/context/base/mkiv/",
-                     "Failed to locate ConTeXt.")
-end
-
-chardef = mkivpath .. "/char-def.lua"
-charini = mkivpath .. "/char-ini.lua"
-
---- we could grab the files from contextgarden but as Context is part
---- of TL it’s not worth bothering
-if not (chardef and lfs.isfile(chardef)) then
-  chardef = assert(kpse.find_file("char-def.lua", "lua"),
-                   "Failed to locate file char-def.lua from ConTeXt.")
-end
-
-if not (charini and lfs.isfile(charini)) then
-  charini = assert(kpse.find_file("char-ini.lua", "lua"),
-                   "Failed to locate file char-ini.lua from ConTeXt.")
-end
-
-io.write(string.format("extracting data from char-def.lua at %s\n",
-                       chardef))
-io.write(string.format("loading code from char-ini.lua at %s\n",
-                       charini))
-
------------------------------------------------------------------------
---                           functionality
------------------------------------------------------------------------
-
-local get_characters = function ( )
-  local data
-  local inchan = io.open(chardef, "r")
-  if not inchan then
-    io.write("Could not open file for reading: "..chardef.."\n.")
-    goto fail
-  end
-  data = inchan:read "*all"
-  inchan:close()
-  data = loadstring(data)
-  if data then
-    data() --> characters.data
-    data = nil
-    collectgarbage "collect"
-    if characters.data and next(characters.data) then
-      return characters.data
-    end
-    io.write "Character table empty.\n"
-    goto fail
-  end
-  io.write(chardef .. " is not a valid Lua file.\n")
-  ::fail::
-  io.write "Emergency exit.\n"
-  os.exit(1)
-end
-
-local extract_fields_indeed
-extract_fields_indeed = function (data, acc, lastidx)
-  local idx, char = next(data, lastidx)
-  if idx then
-    local imported = { }
-    for i=1, #import do
-      local field = import[i]
-      imported[field] = char[field]
-    end
-    acc[idx] = imported
-    return extract_fields_indeed(data, acc, idx)
-  end
-  return acc
-end
-
-local extract_fields = function (data)
-  return extract_fields_indeed(data, {}, nil)
-end
-
---[[ extract_classifiers : from luatex-basics-prepare.tex ]]
-
-local extract_classifiers = function (chardata)
-  dofile (charini)
-  local s_init = 1    local s_rphf =  7
-  local s_medi = 2    local s_half =  8
-  local s_fina = 3    local s_pref =  9
-  local s_isol = 4    local s_blwf = 10
-  local s_mark = 5    local s_pstf = 11
-  local s_rest = 6
-
-  local mappers = {
-    l = s_init,  -- left
-    d = s_medi,  -- double
-    c = s_medi,  -- joiner
-    r = s_fina,  -- right
-    u = s_isol,  -- nonjoiner
-  }
-
-  local first_arabic,  last_arabic  = characters.blockrange("arabic")
-  local first_syriac,  last_syriac  = characters.blockrange("syriac")
-  local first_mandiac, last_mandiac = characters.blockrange("mandiac")
-  local first_nko,     last_nko     = characters.blockrange("nko")
-
-  local classifiers = { }
-
-  for k, c in next, chardata do
-    if k > 0 then
-      local c = chardata[k]
-      if c then
-        local arabic = c.arabic
-        if arabic then
-          classifiers[k] = mappers[arabic]
-          elseif k >= first_arabic  and k <= last_arabic  or k >= first_syriac  and k <= last_syriac  or
-            k >= first_mandiac and k <= last_mandiac or k >= first_nko     and k <= last_nko     then
-            if c.category == "mn" then
-              classifiers[k] = s_mark
-            else
-              classifiers[k] = s_rest
-            end
-          end
-        end
-      end
-    end
-    return classifiers
-  end
-
-local amend_table_fields = function (data, classifiers)
-  --- installed by luatex-basics-prepare.tex
-  data.characters  = { }
-  data.classifiers = classifiers
-  return data
-end
-
-local writedata = function (data)
-  local outchan = io.open(charfile, "w")
-  if not outchan then
-    io.write("Could not open "..charfile.." for writing.\n")
-    return false
-  end
-  outchan:write(data)
-  outchan:close()
-  return true
-end
-
-do
-  local chardata    = get_characters()
-  local classifiers = extract_classifiers(chardata)
-  local stripped    = extract_fields(chardata)
-  local amended     = amend_table_fields(stripped, classifiers)
-  local serialized  = table.serialize(amended, true, {
-    compact   = true,
-    noquotes  = true,
-    hexify    = true, --- for consistency with char-def
-  })
-  if writedata(serialized) then
-    goto done
-  end
-  goto fail
-end
-
-::done::
-  os.exit(0)
-
-::fail::
-  io.write "Emergency exit.\n"
-  os.exit(1)
-
---- vim:ft=lua:ts=2:et:sw=2

Deleted: trunk/Master/texmf-dist/scripts/luaotfload/mkglyphlist
===================================================================
--- trunk/Master/texmf-dist/scripts/luaotfload/mkglyphlist	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/scripts/luaotfload/mkglyphlist	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,167 +0,0 @@
-#!/usr/bin/env texlua
------------------------------------------------------------------------
---         FILE:  mkglyphlist.lua
---        USAGE:  ./mkglyphlist.lua 
---  DESCRIPTION:  part of the luaotfload package
--- REQUIREMENTS:  lua, lpeg, luasocket, the lualibs package
---       AUTHOR:  Philipp Gesang (Phg), <phg42.2a at gmail.com>
------------------------------------------------------------------------
--- interesting thread on the Context list:
--- http://www.ntg.nl/pipermail/ntg-context/2008/029057.html
---
--- N.B. this script assumes network connectivity!
------------------------------------------------------------------------
-
-
------------------------------------------------------------------------
---                              config
------------------------------------------------------------------------
-local glyphfile     = "./build/glyphlist.txt"
-local font_age      = "./build/luaotfload-glyphlist.lua"
-local glyph_source  = "https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt"
-
------------------------------------------------------------------------
---                             fallbacks
------------------------------------------------------------------------
---- Hans adds a small list of mappings that are not in the original
---- glyph list but seem to be normalizations of some sort. I trust his
---- experience, so I’ll just include them here. Background:
---- http://www.ntg.nl/pipermail/ntg-context/2013/073089.html
-
-local fallbacks = {
-  ["SF10000"]=9484, ["SF20000"]=9492, ["SF30000"]=9488,
-  ["SF40000"]=9496, ["SF50000"]=9532, ["SF60000"]=9516,
-  ["SF70000"]=9524, ["SF80000"]=9500, ["SF90000"]=9508,
-  ["afii208"]=8213,
-}
-
------------------------------------------------------------------------
---                             includes
------------------------------------------------------------------------
-require"lpeg"
-require"socket"
-
-kpse.set_program_name"luatex"
-for _, lib in next, { "lualibs-lua.lua",
-                      "lualibs-lpeg.lua",
-                      "lualibs-table.lua", } do
-  local found = assert(kpse.find_file(lib, "lua"),
-                       "Could not locate " .. lib)
-  require(found)
-end
-
-local C, Cf, Cg, Ct, P, R =
-  lpeg.C, lpeg.Cf, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.R
-
-local http = socket.http
-
------------------------------------------------------------------------
---                           functionality
------------------------------------------------------------------------
-
-local dec_of_hex = function (hex) return tonumber(hex, 16) end
-
-local separator    = P";"
-local gartenzaun   = P"#"
-local eol          = P"\n\r" + P"\r\n" + P"\r" + P"\n"
-local space        = P" "
-local alphanum     = R("az", "AZ", "09")
-local hexdigit     = R("af", "AF", "09")
-local eof_tag      = gartenzaun * P"END"
-local header_line  = gartenzaun * (1-eol)^0 * eol
-local codepoint    = hexdigit^1
-local glyphname    = alphanum^1
-
-local definition   = Cg(C(glyphname) * separator * (C(codepoint)/ dec_of_hex))
-                   --- With combined glyphs we take only the first
-                   --- value as char-def and font-age do, and skip
-                   --- the rest.
-                   * (space * codepoint)^0
-                   * eol
-local definitions  = Cf(Ct"" * definition^1, rawset)
-
-local p_glyphs     = header_line^0 * definitions * eof_tag
-
-local get_glyphs = function (data)
-  local res = lpeg.match(p_glyphs, data)
-  if not res then
-    print("error: could not parse glyph list")
-    os.exit(-1)
-  end
-  for name, glyph in next, fallbacks do
-    res[name] = res[name] or glyph
-  end
-  return res
-end
-
-local file_header = [==[
-if not modules then modules = { } end modules ["font-age"] = {
-  version     = 2.400,
-  comment     = "part of the luaotfload package",
-  author      = "luaotfload team / mkglyphlist",
-  copyright   = "derived from %s",
-  original    = "Adobe Glyph List, version 2.0, September 20, 2002",
-  dataonly    = true,
-}
-
-if context then
-  logs.report("fatal error","this module is not for context")
-  os.exit(-1)
-end
-
---[[doc--
-Everything below has been autogenerated. Run mkglyphlist to rebuild
-luaotfload-glyphlist.lua.
---doc]]--
-
-]==]
-
-local writedata = function (data)
-  data = table.serialize(data, true)
-  data = string.format(file_header, glyph_source) .. data
-  local fh = io.open(font_age, "wb")
-  if not fh then
-    print(string.format("error: %s not writable", font_age))
-    os.exit(-1)
-  end
-  print(string.format("saving %d bytes to %s", #data, font_age))
-  fh:write(data)
-  fh:close()
-end
-
-
-local get_raw get_raw = function (retry)
-  local fh = io.open(glyphfile, "rb")
-  if fh then
-    print ("info: reading glyph list from", glyphfile)
-    local data = fh:read"*all"
-    fh:close()
-    if data then return data end
-  elseif not retry then --- attempt download
-    print"info: retrieving glyph list from"
-    print(glyph_source)
-    local cmd = string.format("wget '%s' -o '%s'", glyph_source, glyphfile)
-    local st = os.execute(string.format("wget '%s' -O '%s'", glyph_source, glyphfile))
-    if st ~= 0 then
-      print(string.format("error: download failed; status: %d, command: %q", st, cmd))
-      os.exit(-1)
-    end
-  end
-  print("error: could not obtain glyph data from "..glyphfile)
-  os.exit(-1)
-end
-
-local main = function ()
-  if arg[1] then glyphfile = arg[1] end
-  if arg[2] then font_age  = arg[2] end
-
-  local data    = get_raw()
-  local parsed  = get_glyphs(data)
-  writedata(parsed)
-  return 0
-end
-
-
-return main()
-
---- vim:ft=lua:ts=2:et:sw=2

Deleted: trunk/Master/texmf-dist/scripts/luaotfload/mkimport
===================================================================
--- trunk/Master/texmf-dist/scripts/luaotfload/mkimport	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/scripts/luaotfload/mkimport	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,1063 +0,0 @@
-#!/usr/bin/env texlua
--------------------------------------------------------------------------------
---         FILE:  mkimport.lua
---        USAGE:  texlua ./mkimport.lua
---  DESCRIPTION:  check luaotfload imports against Context
--- REQUIREMENTS:  luatex, the lualibs package, Context MkIV
---       AUTHOR:  Philipp Gesang (Phg), <phg at phi-gamma.net>
--------------------------------------------------------------------------------
---
-
--------------------------------------------------------------------------------
---- PURPOSE
----
----  - Facilitate detecting changes in the fontloader source.
----  - Assist in updating source code and (partially) automate importing.
----
----  - Account for files in the plain fontloader distribution, alert in case of
----    additions or deletions.
----
----  - Fontloader packaging.
----
--------------------------------------------------------------------------------
-
-local debug = false
-
-kpse.set_program_name "luatex"
-
-local lfs = require "lfs"
-local md5 = require "md5"
-local os  = require "os"
-
-require "lualibs"
-require "util-mrg"
-
-assert (utilities and utilities.merger and utilities.merger.compact
-        and type (utilities.merger.compact) == "function",
-        "Whoa, util-mrg.lua is not accessible! How do you expect this to work‽")
-
-local filedirname      = file.dirname
-local fileiswritable   = file.is_writable
-local ioloaddata       = io.loaddata
-local iosavedata       = io.savedata
-local iopopen          = io.popen
-local iowrite          = io.write
-local lfschdir         = lfs.chdir
-local lfscurrentdir    = lfs.currentdir
-local lfsisdir         = lfs.isdir
-local lfsisfile        = lfs.isfile
-local md5sumhexa       = md5.sumhexa
-local osdate           = os.date
-local osgettimeofday   = os.gettimeofday
-local osrename         = os.rename
-local stringformat     = string.format
-local tableconcat      = table.concat
-
--------------------------------------------------------------------------------
--- config
--------------------------------------------------------------------------------
-
-local parms               = { }
-local our_prefix          = "fontloader"
-local luatex_fonts_prefix = "luatex"
-local fontloader_subdir   = "src/fontloader"
-
-local origin_paths = {
-  context    = { "tex/context/base/mkiv", "tex/context/base", },
-  fontloader = "tex/generic/context/luatex",
-}
-
-local subdirs = {
-  "runtime",
-  "misc"
-}
-
-local searchdirs = {
-  --- order is important!
-  fontloader_subdir,
-}
-
-local prefixes = {
-  context    = nil,
-  fontloader = "luatex",
-}
-
---[[doc--
-
-    The output name is fixed so we have to deal with it but maybe we
-    can get a patch to mtx-package upstreamed in the future. In any
-    case, we are content with renaming the result for the time being.
-
-    The target name is constructed on the fly from the current date.
-    TODO It should be possible to supply a name and possibly
-    destination path on the command line.
-
-    Paths are relative to the base directory (``$PWD``).
-
---doc]]--
-
-local loader_target_name = "fontloader-%s.lua"
-local loader_orig_dir    = "/src/fontloader/"
-local loader_target_dir  = "/build/"
-
--------------------------------------------------------------------------------
--- helpers
--------------------------------------------------------------------------------
-
-local die = function (...)
-  io.stderr:write "[\x1b[1;30;41mfatal error\x1b[0m] "
-  io.stderr:write (stringformat (...))
-  io.stderr:write "\naborting.\n"
-  os.exit (1)
-end
-
-local uncertain = 0
-
-local hmm = function (...)
-  uncertain = uncertain + 1
-  --[[ sorta like an error but non-fatal ]]
-  io.stderr:write "[\x1b[1;31merror\x1b[0m] "
-  io.stderr:write (stringformat (...))
-  io.stderr:write "; continuing nontheless.\n"
-end
-
-local emphasis = function (txt)
-  return stringformat("\x1b[1m%s\x1b[0m", txt)
-end
-
-local msg = function (...)
-  iowrite (stringformat (...))
-  iowrite "\n"
-end
-
-local separator_string = string.rep ("-", 79)
-local separator = function ()
-  iowrite (separator_string)
-  iowrite "\n"
-end
-
-local good_tag   = stringformat("[\x1b[1;30;%dmgood\x1b[0m]   · ", 42)
-local bad_tag    = stringformat("[\x1b[1;30;%dmBAD\x1b[0m]    · ", 41)
-local alert_tag  = stringformat("[\x1b[1;%dmalert\x1b[0m]  · "   , 36)
-local status_tag = stringformat("[\x1b[0;%dmstatus\x1b[0m] · "   , 36)
-
-local good = function (...)
-  local msg = (stringformat (...))
-  iowrite (good_tag)
-  iowrite (msg)
-  iowrite "\n"
-end
-
-local bad = function (...)
-  local msg = (stringformat (...))
-  iowrite (bad_tag)
-  iowrite (msg)
-  iowrite "\n"
-end
-
-local attention = function (...)
-  local msg = (stringformat (...))
-  iowrite (alert_tag)
-  iowrite (msg)
-  iowrite "\n"
-end
-
-local status = function (...)
-  local msg = (stringformat (...))
-  iowrite (status_tag)
-  iowrite (msg)
-  iowrite "\n"
-end
-
--------------------------------------------------------------------------------
--- definitions
--------------------------------------------------------------------------------
-
---- Accounting of upstream files. There are different categories:
----
----   · *essential*: Files required at runtime.
----   · *merged*:    Files merged into the fontloader package.
----   · *ignored*:   Lua files not merged, but part of the format.
----   · *tex*:       TeX code, i.e. format and examples.
----   · *lualibs*:   Files merged, but also provided by the Lualibs package.
-
-local kind_essential = 0
-local kind_merged    = 1
-local kind_tex       = 2
-local kind_ignored   = 3
-local kind_lualibs   = 4
-
-local kind_name = {
-  [0] = "essential",
-  [1] = "merged"   ,
-  [2] = "tex"      ,
-  [3] = "ignored"  ,
-  [4] = "lualibs"  ,
-}
-
-local imports = {
-
-  fontloader = {
-    { name = "basics-gen"        , ours = nil          , kind = kind_essential },
-    { name = "basics-nod"        , ours = nil          , kind = kind_merged    },
-    { name = "basics"            , ours = nil          , kind = kind_tex       },
-    { name = "fonts-demo-vf-1"   , ours = nil          , kind = kind_ignored   },
-    { name = "fonts-enc"         , ours = nil          , kind = kind_merged    },
-    { name = "fonts-ext"         , ours = nil          , kind = kind_merged    },
-    { name = "fonts-merged"      , ours = "reference"  , kind = kind_essential },
-    { name = "fonts"             , ours = nil          , kind = kind_merged    },
-    { name = "fonts"             , ours = nil          , kind = kind_tex       },
-    { name = "fonts-syn"         , ours = nil          , kind = kind_ignored   },
-    { name = "languages"         , ours = nil          , kind = kind_ignored   },
-    { name = "languages"         , ours = nil          , kind = kind_tex       },
-    { name = "math"              , ours = nil          , kind = kind_ignored   },
-    { name = "math"              , ours = nil          , kind = kind_tex       },
-    { name = "mplib"             , ours = nil          , kind = kind_ignored   },
-    { name = "mplib"             , ours = nil          , kind = kind_tex       },
-    { name = "plain"             , ours = nil          , kind = kind_tex       },
-    { name = "preprocessor"      , ours = nil          , kind = kind_ignored   },
-    { name = "preprocessor"      , ours = nil          , kind = kind_tex       },
-    { name = "preprocessor-test" , ours = nil          , kind = kind_tex       },
-    { name = "swiglib"           , ours = nil          , kind = kind_ignored   },
-    { name = "swiglib"           , ours = nil          , kind = kind_tex       },
-    { name = "swiglib-test"      , ours = nil          , kind = kind_ignored   },
-    { name = "swiglib-test"      , ours = nil          , kind = kind_tex       },
-    { name = "test"              , ours = nil          , kind = kind_tex       },
-  }, --[[ [fontloader] ]]
-
-  context = { --=> all merged
-    { name = "data-con"          , ours = "data-con"          , kind = kind_merged    },
-    { name = "font-afk"          , ours = "font-afk"          , kind = kind_merged    },
-    { name = "font-cff"          , ours = "font-cff"          , kind = kind_merged    },
-    { name = "font-cid"          , ours = "font-cid"          , kind = kind_merged    },
-    { name = "font-con"          , ours = "font-con"          , kind = kind_merged    },
-    { name = "font-def"          , ours = "font-def"          , kind = kind_merged    },
-    { name = "font-dsp"          , ours = "font-dsp"          , kind = kind_merged    },
-    { name = "font-gbn"          , ours = "font-gbn"          , kind = kind_merged    },
-    { name = "font-ini"          , ours = "font-ini"          , kind = kind_merged    },
-    { name = "font-lua"          , ours = "font-lua"          , kind = kind_merged    },
-    { name = "font-map"          , ours = "font-map"          , kind = kind_merged    },
-    { name = "font-ocl"          , ours = "font-ocl"          , kind = kind_merged    },
-    { name = "font-otc"          , ours = "font-otc"          , kind = kind_merged    },
-    { name = "font-onr"          , ours = "font-onr"          , kind = kind_merged    },
-    { name = "font-one"          , ours = "font-one"          , kind = kind_merged    },
-    { name = "font-osd"          , ours = "font-osd"          , kind = kind_merged    },
-    { name = "font-ota"          , ours = "font-ota"          , kind = kind_merged    },
-    { name = "font-oti"          , ours = "font-oti"          , kind = kind_merged    },
-    { name = "font-otj"          , ours = "font-otj"          , kind = kind_merged    },
-    { name = "font-otl"          , ours = "font-otl"          , kind = kind_merged    },
-    { name = "font-oto"          , ours = "font-oto"          , kind = kind_merged    },
-    { name = "font-otr"          , ours = "font-otr"          , kind = kind_merged    },
-    { name = "font-ots"          , ours = "font-ots"          , kind = kind_merged    },
-    { name = "font-oup"          , ours = "font-oup"          , kind = kind_merged    },
-    { name = "font-tfm"          , ours = "font-tfm"          , kind = kind_merged    },
-    { name = "font-ttf"          , ours = "font-ttf"          , kind = kind_merged    },
-
-    { name = "l-boolean"         , ours = "l-boolean"         , kind = kind_lualibs   },
-    { name = "l-file"            , ours = "l-file"            , kind = kind_lualibs   },
-    { name = "l-function"        , ours = "l-function"        , kind = kind_lualibs   },
-    { name = "l-io"              , ours = "l-io"              , kind = kind_lualibs   },
-    { name = "l-lpeg"            , ours = "l-lpeg"            , kind = kind_lualibs   },
-    { name = "l-lua"             , ours = "l-lua"             , kind = kind_lualibs   },
-    { name = "l-math"            , ours = "l-math"            , kind = kind_lualibs   },
-    { name = "l-string"          , ours = "l-string"          , kind = kind_lualibs   },
-    { name = "l-table"           , ours = "l-table"           , kind = kind_lualibs   },
-    { name = "util-str"          , ours = "util-str"          , kind = kind_lualibs   },
-    { name = "util-fil"          , ours = "util-fil"          , kind = kind_lualibs   },
-  }, --[[ [context] ]]
-} --[[ [imports] ]]
-
-local package = {
-
-  optional = { --- components not included in the default package
-
---- The original initialization sequence by Hans Hagen, see the file
---- luatex-fonts.lua for details:
----
----   [01] l-lua.lua
----   [02] l-lpeg.lua
----   [03] l-function.lua
----   [04] l-string.lua
----   [05] l-table.lua
----   [06] l-io.lua
----   [07] l-file.lua
----   [08] l-boolean.lua
----   [09] l-math.lua
----   [10] util-str.lua
----   [11] util-fil.lua
----   [12] luatex-basics-gen.lua
----   [13] data-con.lua
----   [14] luatex-basics-nod.lua
----   [15] luatex-basics-chr.lua
----   [16] font-ini.lua
----   [17] font-con.lua
----   [18] luatex-fonts-enc.lua
----   [19] font-cid.lua
----   [20] font-map.lua
----   [21] luatex-fonts-syn.lua
----   [23] font-oti.lua
----   [24] font-otr.lua
----   [25] font-cff.lua
----   [26] font-ttf.lua
----   [27] font-dsp.lua
----   [28] font-oup.lua
----   [29] font-otl.lua
----   [30] font-oto.lua
----   [31] font-otj.lua
----   [32] font-ota.lua
----   [33] font-ots.lua
----   [34] font-osd.lua
----   [35] font-ocl.lua
----   [36] font-otc.lua
----   [37] font-onr.lua
----   [38] font-one.lua
----   [39] font-afk.lua
----   [40] font-tfm.lua
----   [41] font-lua.lua
----   [42] font-def.lua
----   [43] font-xtx.lua
----   [44] luatex-fonts-ext.lua
----   [45] font-gbn.lua
----
---- Of these, nos. 01--11 are provided by the Lualibs. Keeping them
---- around in the Luaotfload fontloader is therefore unnecessary.
---- Packaging needs to account for this difference.
-
-    "l-lua",
-    "l-lpeg",
-    "l-function",
-    "l-string",
-    "l-table",
-    "l-io",
-    "l-file",
-    "l-boolean",
-    "l-math",
-    "util-str",
-    "util-fil",
-
---- Another file containing auxiliary definitions must be present
---- prior to initialization of the configuration.
-
-    "luatex-basics-gen",
-
---- We have a custom script for autogenerating data so we don’t use the
---- definitions from upstream.
-
-    "basics-chr",
-
-  }, --[[ [package.optional] ]]
-
---- The files below constitute the “fontloader proper”. Some of the
---- functionality like file resolvers is overloaded later by
---- Luaotfload. Consequently, the resulting package is pretty
---- bare-bones and not usable independently.
-
-  required = {
-
-    "data-con",
-    "basics-nod",
-    "font-ini",
-    "font-con",
-    "fonts-enc",
-    "font-cid",
-    "font-map",
-    "font-oti",
-    "font-otr",
-    "font-cff",
-    "font-ttf",
-    "font-dsp",
-    "font-oup",
-    "font-otl",
-    "font-oto",
-    "font-otj",
-    "font-ota",
-    "font-ots",
-    "font-osd",
-    "font-ocl",
-    "font-otc",
-    "font-onr",
-    "font-one",
-    "font-afk",
-    "font-tfm",
-    "font-lua",
-    "font-def",
-    "fonts-ext",
-    "font-gbn",
-
-  }, --[[ [package.required] ]]
-
-} --[[ [package] ]]
-
-local hash_file = function (fname)
-  if not lfsisfile (fname) then
-    hmm ("cannot find %s", fname)
-    return nil
-  end
-  local raw = ioloaddata (fname)
-  if not raw then
-    die ("cannot read from %s.", fname)
-  end
-  return md5sumhexa (raw)
-end
-
-local first_existing_subpath = function (pfx, subs)
-  if not subs then return nil end
-  local t_subs = type (subs)
-  if t_subs == "table" then
-    for i = 1, #subs do
-      local sub = subs[i]
-      local pth = file.join (pfx, sub)
-      if lfsisdir (pth) then return pth end
-    end
-  elseif t_subs == "string" then
-    local pth = file.join (pfx, subs)
-    if lfsisdir (pth) then return pth end
-  end
-  return nil
-end
-
-local derive_category_path = function (cat)
-  local location = first_existing_subpath (parms.context_root,
-                                           origin_paths[cat])
-  if not location then
-    die ("invalid base path defined for category " .. cat)
-  end
-  return location
-end
-
-local derive_suffix = function (kind)
-  if kind == kind_tex then return ".tex" end
-  return ".lua"
-end
-
-local pfxlen = { }
-local strip_prefix = function (fname, prefix)
-  prefix = prefix or our_prefix
-  if not pfxlen[prefix] then pfxlen[prefix] = #prefix end
-  local len = pfxlen[prefix]
-  if #fname <= len + 2 then
-    --- too short to accomodate prefix + basename
-    return
-  end
-  if string.sub (fname, 1, len) == prefix then
-    return string.sub (fname, len + 2)
-  end
-end
-
-local derive_fullname = function (cat, name, kind)
-  local tmp = prefixes[cat]
-  tmp = tmp and tmp .. "-" .. name or name
-  return tmp .. derive_suffix (kind)
-end
-
-local derive_ourname = function (name, kind)
-  local suffix = derive_suffix (kind)
-  local subdir = kind == kind_essential and "runtime" or "misc"
-  return subdir, our_prefix .. "-" .. name .. suffix
-end
-
-local format_file_definition = function (def)
-  return stringformat ("name = \"%s\", kind = \"%s\"",
-                       def.name,
-                       kind_name[def.kind] or def.kind)
-      .. (def.ours and (", ours = \"" .. def.ours .. "\"") or "")
-end
-
-local is_readable = function (f)
-  local fh = io.open (f, "r")
-  if fh then
-    fh:close()
-    return true
-  end
-  return false
-end
-
-local summarize_news = function (status)
-  local ni = #status.import
-  local nc = #status.create
-  local ng = #status.good
-  local nm = #status.missing
-
-  separator ()
-  msg ("Summary: Inspected %d files.", ni + nc + ng + nm)
-  separator ()
-  if ng > 0 then good      ("%d are up to date", ng) end
-  if ni > 0 then attention ("%d changed"       , ni) end
-  if nc > 0 then attention ("%d new"           , nc) end
-  if nm > 0 then bad       ("%d missing"       , nm) end
-  separator ()
-
-  if nm == 0 and nc == 0 and ni == 0 then
-    return 0
-  end
-
-  return -1
-end
-
-local news = function ()
-  local status = {
-    import  = { },
-    good    = { },
-    create  = { },
-    missing = { },
-  }
-
-  for cat, entries in next, imports do
-    local location = derive_category_path (cat)
-    local nfiles = #entries
-
-    for i = 1, nfiles do
-      local def  = entries[i]
-      local name = def.name
-      local ours = def.ours
-      local kind = def.kind
-      local fullname = derive_fullname (cat, name, kind)
-      local fullpath = file.join (location, fullname)
-      local subdir, ourname  = derive_ourname (ours or name, kind)
-      local ourpath  = file.join (fontloader_subdir, subdir, ourname) -- relative
-      local imported = false
-
-      if not is_readable (fullpath) then
-        bad ("source for file %s not found at %s",
-             emphasis (ourname),
-             emphasis (fullpath))
-        status.missing[#status.missing + 1] = ourname
-      else
-        --- Source file exists and is readable.
-        if not lfsisdir (fontloader_subdir) then
-          die ("path for fontloader tree ("
-              .. fontloader_subdir .. ") is not a directory")
-        end
-        if is_readable (ourpath) then imported = true end
-        local src_hash = hash_file (fullpath)
-        if src_hash then
-          local dst_hash = imported and hash_file (ourpath)
-          local same     = src_hash == dst_hash -- same!
-          if same then
-            good ("file %s unchanged", emphasis (ourname))
-            status.good[#status.good + 1] = ourname
-          elseif not dst_hash then
-            attention ("new file %s requires import from %s",
-                      emphasis (ourname),
-                      emphasis (fullpath))
-            status.create[#status.create + 1] = ourname
-          else --- src and dst exist but differ
-            attention ("file %s requires import", emphasis (ourname))
-            status.import[#status.import + 1] = ourname
-          end
-        end
-      end
-
-    end
-  end
-
-  return summarize_news (status)
-end --[[ [local news = function ()] ]]
-
-local get_file_definition = function (name, ourname, kind)
-  kind = kind or "lua"
-  for cat, defs in next, imports do
-    local fullname = derive_fullname (cat, name, kind)
-    local ndefs = #defs
-    for i = 1, ndefs do
-      local def = defs[i]
-      local dname = def.name
-      local dours = def.ours or def.name
-      local dkind = def.kind
-
-      --- test properties
-      local subdir, derived = derive_ourname (dours, dkind)
-      if                             derived == ourname  then return def, cat end
-      if derive_fullname (cat, dname, dkind) == fullname then return def, cat end
-      if                               dours == ourname  then return def, cat end
-      if                               dname == fullname then return def, cat end
-    end
-  end
-  --- search unsuccessful
-end --[[ [local get_file_definition = function (name, ourname, kind)] ]]
-
-local import_imported = 0
-local import_skipped  = 1
-local import_failed   = 2
-local import_created  = 3
-
-local import_status = {
-  [import_imported] = "imported",
-  [import_skipped ] = "skipped",
-  [import_failed  ] = "failed",
-  [import_created ] = "created",
-}
-
-local summarize_status = function (counters)
-  local imported = counters[import_imported] or 0
-  local skipped  = counters[import_skipped ] or 0
-  local created  = counters[import_created ] or 0
-  local failed   = counters[import_failed  ] or 0
-  local sum = imported + skipped + created + failed
-  if sum < 1 then die ("garbage total of imported files: %s", sum) end
-  separator ()
-  status (" RESULT: %d files processed, %d errors", sum, uncertain)
-  separator ()
-  if created  > 0 then status ("created:  %d (%d %%)", created , created  * 100 / sum) end
-  if imported > 0 then status ("imported: %d (%d %%)", imported, imported * 100 / sum) end
-  if skipped  > 0 then status ("skipped:  %d (%d %%)", skipped , skipped  * 100 / sum) end
-  separator ()
-end
-
-local import_file = function (name, kind, def, cat)
-  local expected_ourname = derive_ourname (name)
-  if not def or not cat then
-    def, cat = get_file_definition (name, expected_ourname, kind)
-  end
-
-  if not def then die ("unable to find a definition matching " .. name) end
-  if not cat then die ("missing category for file " .. name .. " -- WTF‽") end
-
-  local dname    = def.name
-  local dours    = def.ours or dname
-  local dkind    = def.kind
-  local srcdir   = derive_category_path (cat)
-  local fullname = derive_fullname (cat, dname, kind)
-  local subdir, ourname = derive_ourname (dours, kind)
-  local ourpath  = file.join (fontloader_subdir, subdir)
-  local src      = file.join (srcdir, fullname)
-  local dst      = file.join (ourpath, ourname)
-  local new      = not lfsisfile (dst)
-  if not new and hash_file (src) == hash_file (dst) then
-    status ("file %s is unchanged, skipping", fullname)
-    return import_skipped
-  end
-  if not (lfsisdir (ourpath) or not lfs.mkdirs (ourpath)) then
-    die ("failed to create directory %s for file %s",
-         ourpath, ourname)
-  end
-  status ("importing file %s", fullname)
-  file.copy (src, dst)
-  if hash_file (src) == hash_file (dst) then
-    if new then return import_created end
-    return import_imported end
-  return import_failed
-end --[[ [local import_file = function (name, kind)] ]]
-
-local import = function (arg)
-  --- Multiple files
-  local statcount = { } -- import status codes -> size_t
-  for cat, defs in next, imports do
-    local ndefs = #defs
-    for i = 1, ndefs do
-      local def  = defs[i]
-      local stat = import_file (def.name, def.kind, def, cat)
-      if stat == import_failed then
-        hmm (stringformat ("import failed at file %d of %d (%s)",
-                           i, ndefs, def.name))
-      end
-      statcount[stat] = statcount[stat] or 0
-      statcount[stat] = statcount[stat] + 1
-    end
-  end
-  summarize_status (statcount)
-  return uncertain == 0 and 0 or -42
-end --[[ [local import = function (arg)] ]]
-
-local find_in_path = function (root, subdir, target)
-  local file = file.join (root, subdir, target)
-  if lfsisfile (file) then
-    return file
-  end
-end
-
-local search_paths = function (target)
-  for i = 1, #searchdirs do
-    local root  = searchdirs[i]
-
-    for j = 1, #subdirs do
-      local found = find_in_path (root, subdirs[j], target)
-      if found then return found end
-    end
-
-  end
-
-  local found = find_in_path (parms.context_root, origin_paths.context, target)
-  if found then return found end
-
-  local found = find_in_path (parms.context_root, origin_paths.fontloader, target)
-  if found then return found end
-  return false
-end
-
-local search_defs = function (target)
-  local variants = { target, --[[ unstripped ]] }
-  local tmp
-  tmp = strip_prefix (target)
-  if tmp then variants[#variants + 1] = tmp end
-  tmp = strip_prefix (target, luatex_fonts_prefix)
-  if tmp then variants[#variants + 1] = tmp end
-
-  local nvariants = #variants
-
-  for cat, defs in next, imports do
-    local ndefs = #defs
-    for i = 1, ndefs do
-      local def = defs[i]
-
-      for i = 1, nvariants do
-        local variant = variants[i]
-
-        local dname = def.name
-        if variant == dname then
-          local found = search_paths (variant .. derive_suffix (def.kind))
-          if found then return found end
-        end
-
-        local dkind = def.kind
-        local dfull = derive_fullname (cat, dname, dkind)
-        if derive_fullname (cat, variant, dkind) == dfull then
-          local found = search_paths (dfull)
-          if found then return found end
-        end
-
-        local dours = def.ours
-        if dours then
-
-          local _, ourname = derive_ourname (dours, dkind)
-          if variant == dours then
-            local found = search_paths (ourname)
-            if found then return found end
-          end
-
-          if variant == ourname then
-            local found = search_paths (ourname)
-            if found then return found end
-          end
-        end
-
-      end
-    end
-  end
-  return false
-end
-
-local search = function (target)
-  local look_for
-  --- pick a file
-  if lfsisfile (target) then --- absolute path given
-    look_for = target
-    goto found
-  else
-
-    --- search as file name in local tree
-    look_for = search_paths (target)
-    if look_for then goto found end
-
-    --- seach the definitions
-    look_for = search_defs (target)
-    if look_for then goto found end
-
-  end
-
-::fail::
-  if not look_for then return end
-
-::found::
-  return look_for
-end
-
-local find_matching_def = function (location)
-  local basename = file.basename (location)
-  if not basename then die ("corrupt path %s", location) end
-  local barename = file.removesuffix (basename)
-  local pfxless  = strip_prefix (barename)
-  local kind     = file.suffix (pfxless) or "lua"
-  for cat, defs in next, imports do
-    for _, def in next, defs do
-      local dname = def.name
-      local dours = def.ours
-      if dname == pfxless
-      or dname == barename
-      -- dname == basename -- can’t happen for lack of suffix
-      or dours == pfxless
-      or dours == barename
-      then
-        return cat, def
-      end
-    end
-  end
-  return false
-end
-
-local describe = function (target, location)
-  --- Map files to import definitions
-  separator ()
-  status ("found file %s at %s", target, location)
-  local cat, def = find_matching_def (location)
-  if not cat or not def then
-    die ("file %s not found in registry", location)
-  end
-
-  local dname           = def.name
-  local dkind           = def.kind
-  local subdir, ourname = derive_ourname (def.ours or dname, dkind)
-  separator ()
-  status ("category       %s", cat)
-  status ("kind           %s", kind_name[dkind])
-  status ("in Context     %s", derive_fullname (cat, dname, dkind))
-  status ("in Luaotfload  %s", ourname)
-  separator ()
-  return 0
-end
-
-local tell = function (arg)
-  local target = parms.target
-  if not target then die "no filename given" end
-
-  local location = search (target)
-  if not location then
-    die ("file %s not found in any of the search locations", target)
-  end
-
-  return describe (target, location)
-end
-
-local build_paths = function (argv)
-  if not argv or type (argv) ~= "table" then die "build_paths" end
-
-  local orig_dir    = lfscurrentdir ()
-  local base_dir    = orig_dir .. loader_orig_dir
-  local loader_name = stringformat (loader_target_name, os.date ("%F"))
-  local target_name = orig_dir .. loader_target_dir .. loader_name
-
-  if #argv >= 2 then
-    local fname = argv[2]
-    local dir   = filedirname (fname) .. "/"
-    if not lfsisdir (dir) then
-      die ("second argument must be point into existing directory, not “%s”",
-           argv[2])
-    end
-    base_dir    = dir
-    target_name  = fname
-  end
-
-  if #argv == 3 then
-    --- also set the target name
-    local fname = argv[3]
-    local dir   = filedirname (fname)
-    if not string.is_empty (dir) and not lfsisdir (dir) then
-      die ("third argument must be point into writable directory, not “%s”",
-           argv[3])
-    end
-    target_name = fname
-  end
-
-  local ret = {
-    orig_dir    = orig_dir,
-    base_dir    = base_dir,
-    merge_name  = merge_name,
-    target_name = target_name,
-    loader_name = loader_name,
-  }
-  return ret
-end
-
-local luaotfload_header = [==[
---[[info-----------------------------------------------------------------------
-  Luaotfload fontloader package
-  build %s by %s@%s
--------------------------------------------------------------------------------
-
-  © %s PRAGMA ADE / ConTeXt Development Team
-
-  The code in this file is provided under the GPL v2.0 license. See the
-  file COPYING in the Luaotfload repository for details.
-
-  Report bugs to github.com/lualatex/luaotfload
-
-  This file has been assembled from components taken from Context. See
-  the Luaotfload documentation for details:
-
-      $ texdoc luaotfload
-      $ man 1 luaotfload-tool
-      $ man 5 luaotfload.conf
-
-  Included files:
-
-%s
-
---info]]-----------------------------------------------------------------------
-
-]==]
-
-local make_header = function (files)
-  local filelist = { }
-  for i = 1, #files do
-    local f = files[i]
-    local _void, ourname = derive_ourname (f, kind_merged)
-    filelist [#filelist + 1] = stringformat ("    · %s", ourname)
-  end
-  return stringformat (luaotfload_header,
-                       os.date "%F %T",
-                       os.getenv "USER" or "anon",
-                       os.getenv "HOSTNAME" or "void",
-                       os.date "%Y",
-                       table.concat (filelist, "\n"))
-end
-
-
-local scope_start         = "\ndo  --- [luaotfload, %s scope for “%s” %s] ---\n\n"
-local scope_stop          = "\nend --- [luaotfload, %s scope for “%s”] ---\n\n"
-local luaotfload_modeline = "\n--- vim:ft=lua:sw=2:ts=8:et:tw=79\n"
-
-local assemble_fontloader = function (tgt, dst)
-  status ("packaging fontloader as “%s”.", emphasis (tgt))
-  local required  = package.required
-  local compact   = utilities.merger.compact
-  local sequence  = { [1] = make_header (required) }
-  for i = 1, #required do
-    local cur = required [i]
-    local subdir, ourname = derive_ourname (cur, kind_merged)
-    local ourpath = file.join (fontloader_subdir, subdir, ourname)
-    local data = ioloaddata (ourpath)
-    if not data then
-      bad ("file “%s” cannot be loaded from “%s”", ourname, ourpath)
-      return false
-    end
-    sequence[#sequence + 1] = stringformat (scope_start, tgt, cur, md5sumhexa (data))
-    sequence[#sequence + 1] = compact (data)
-    sequence[#sequence + 1] = stringformat (scope_stop , tgt, cur)
-  end
-  sequence[#sequence + 1] = luaotfload_modeline
-  local raw = table.concat (sequence)
-  local _void, chunk, err = pcall (loadstring, raw)
-  print(_void, chunk)
-  if chunk == nil then
-    bad ("packaging result not well-formed")
-    bad ("error message: “%s”", err)
-    bad ("dumping to fontloader-junk.lua")
-    iosavedata ("fontloader-junk.lua", raw)
-    return false
-  end
-  iosavedata (dst, raw)
-  status ("amalgamated %d files, written to “%s”.",
-          #required, dst)
-  return dst
-end
-
-local package = function (argv)
-  local t0    = osgettimeofday ()
-  local paths = build_paths (argv)
-
-  status ("assuming fontloader source in      %s", paths.base_dir)
-  status ("reading merge instructions from    %s", paths.merge_name)
-  status ("writing output to                  %s", paths.target_name)
-
-  --- check preconditions
-
-  if not lfsisdir (paths.base_dir)          then die ("directory %s does not exist", emphasis (paths.base_dir   )) end
-  if not fileiswritable (paths.target_name) then die ("cannot write to %s",          emphasis (paths.target_name)) end
----- not lfschdir (paths.base_dir)          then die ("failed to cd into %s",        emphasis (paths.base_dir   )) end
-
-  if lfsisfile (paths.target_name) then
-    status ("output file already exists at “%s”, unlinking",
-            paths.target_name)
-    local ret, err = os.remove (paths.target_name)
-    if ret == nil then
-      if not lfschdir (paths.orig_dir) then
-        status ("warning: failed to cd retour into %s",
-                emphasis (paths.orig_dir))
-      end
-      die ("failed to remove existing merge package")
-    end
-  end
-  --- perform merge
-
-  local ret = assemble_fontloader (paths.loader_name, paths.target_name)
-
-  if not ret then
-    if not lfschdir (paths.orig_dir) then
-      status ("warning: failed to cd retour into %s",
-              emphasis (paths.orig_dir))
-    end
-    die ("merge failed; failed to invoke mtxrun")
-  end
-
-  --- clean up
-
-  if not lfschdir (paths.orig_dir) then
-    status ("warning: failed to cd retour into %s",
-            emphasis (paths.orig_dir))
-  end
-
-  --- check postconditions
-
-  if not lfsisfile (ret) then
-    die ("merge failed; package not found at “%s”", paths.output_name)
-  end
-
-  --- at this point we know that mtxrun was invoked correctly and the
-  --- result file has been created
-
-  status ("merge complete; operation finished in %.0f ms",
-          (osgettimeofday() - t0) * 1000)
-  status ("a fresh fontloader at %s is ready to roll", paths.target_name)
-end
-
-local help = function ()
-  iowrite "usage: mkimport  <command> [<args>]\n"
-  iowrite "\n"
-  iowrite "Where <command> is one of\n"
-  iowrite "   help      Print this help message\n"
-  iowrite "   tell      Display information about a file’s integration\n"
-  iowrite "   news      Check Context for updated files\n"
-  iowrite "   import    Update with files from Context\n"
-  iowrite "   package   Invoke mtx-package on the current fontloader\n"
-  iowrite "\n"
-end
-
-local job_kind = table.mirrored {
-  help    = help,
-  import  = import,
-  news    = news,
-  package = package,
-  tell    = tell,
-}
-
--------------------------------------------------------------------------------
--- functionality
--------------------------------------------------------------------------------
-
---- job_kind -> bool
-local check_job = function (j)
-  return job_kind[j] or die ("invalid job type “%s”.", j)
-end
-
-local parse_argv = function (argv)
-  local job
-  local tgt
-  local pth
-
-  local argc = #arg
-  if argc < 1 or argc > 3 then return "help" end
-  job = arg[1] or "help"
-  if argc > 1 then
-    tgt = arg[2]
-    if argc == 3 then pth = arg[3] end
-  end
-  if not pth then pth = "~/context/tex/texmf-context" end
-  parms.context_root = kpse.expand_path (pth)
-  parms.target       = tgt
-  searchdirs [#searchdirs + 1] = pth
-  return job
-end
-
--------------------------------------------------------------------------------
--- entry point
--------------------------------------------------------------------------------
-
-local main = function ()
-  local job = parse_argv (arg)
-  local runner = check_job (job)
-  return runner(arg)
-end
-
-os.exit (main ())
-
---- vim:ft=lua:ts=2:et:sw=2

Deleted: trunk/Master/texmf-dist/scripts/luaotfload/mkstatus
===================================================================
--- trunk/Master/texmf-dist/scripts/luaotfload/mkstatus	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/scripts/luaotfload/mkstatus	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,307 +0,0 @@
-#!/usr/bin/env texlua
------------------------------------------------------------------------
---         FILE:  mkstatus.lua
---        USAGE:  ./mkstatus.lua
---  DESCRIPTION:  writes the repository state
--- REQUIREMENTS:  luatex, the lualibs package
---       AUTHOR:  Philipp Gesang (Phg), <phg42.2a at gmail.com>
---      CREATED:  2013-07-07 14:01:12+0200
------------------------------------------------------------------------
---
--- This script generates a list of hashes that serves as the input
--- for the file integrity check (option --diagnose). md5 is all we can
--- assume in Luatex, so it’s really only a superficial test.
---
--- Not that this file also incorporates the Git revision information.
--- Of this, only the actual commit hash is authoritative. The latest
--- tag is included for reference only. Besides that, it’s meaningless.
--- Do not rely on it: Two distinct versions of Luaotfload might very
--- well share the same tag.
-
-kpse.set_program_name "luatex"
-
-local md5 = require "md5"
-
-require "lualibs"
-
-local stringformat = string.format
-local md5sumhexa   = md5.sumhexa
-local ioloaddata   = io.loaddata
-local iosavedata   = io.savedata
-local iopopen      = io.popen
-local iowrite      = io.write
-local lfsisdir     = lfs.isdir
-local stringmatch  = string.match
-
------------------------------------------------------------------------
--- settings
------------------------------------------------------------------------
-
-local verbose  = false
-local filelist = "./build/luaotfload-status.lua" --- result
-
-local srcdir    = "src"
-local builddir  = "build"
-local scriptdir = "scripts"
-local loaderdir = "src/fontloader"
-local rtdir     = "src/fontloader/runtime"
-local miscdir   = "src/fontloader/misc"
-
-local names = {
-
-  --- Luaotfload runtime files
-  { srcdir,       "luaotfload-auxiliary.lua",       },
-  { srcdir,       "luaotfload-colors.lua",          },
-  { srcdir,       "luaotfload-configuration.lua",   },
-  { srcdir,       "luaotfload-database.lua",        },
-  { srcdir,       "luaotfload-diagnostics.lua",     },
-  { srcdir,       "luaotfload-features.lua",        },
-  { srcdir,       "luaotfload-init.lua",            },
-  { srcdir,       "luaotfload-letterspace.lua",     },
-  { srcdir,       "luaotfload-loaders.lua",         },
-  { srcdir,       "luaotfload-log.lua",             },
-  { srcdir,       "luaotfload-main.lua",            },
-  { srcdir,       "luaotfload-parsers.lua",         },
-  { srcdir,       "luaotfload-resolvers.lua",       },
-  { srcdir,       "luaotfload-tool.lua",            },
-
-  --- generated files
-  { builddir,     "luaotfload-characters.lua",      },
-  { builddir,     "luaotfload-glyphlist.lua",       },
-
-  --- scripts
-  { scriptdir,    "mkcharacters",                   },
-  { scriptdir,    "mkglyphlist",                    },
-  { scriptdir,    "mkimport",                       },
-  { scriptdir,    "mkstatus",                       },
-  { scriptdir,    "mktests",                        },
-
-  --- fontloader runtimes
-  { rtdir,        "fontloader-basics-gen.lua",      },
-  { rtdir,        "fontloader-reference.lua",       },
-
-  --- fontloader constituents
-  { miscdir,      "fontloader-basics-nod.lua",      },
-  { miscdir,      "fontloader-data-con.lua",        },
-  { miscdir,      "fontloader-font-afk.lua",        },
-  { miscdir,      "fontloader-font-onr.lua",        },
-  { miscdir,      "fontloader-font-one.lua",        },
-  { miscdir,      "fontloader-font-cid.lua",        },
-  { miscdir,      "fontloader-font-con.lua",        },
-  { miscdir,      "fontloader-font-def.lua",        },
-  { miscdir,      "fontloader-font-ini.lua",        },
-  { miscdir,      "fontloader-font-map.lua",        },
-  { miscdir,      "fontloader-font-oti.lua",        },
-  { miscdir,      "fontloader-font-gbn.lua",        },
-  { miscdir,      "fontloader-font-def.lua",        },
-  { miscdir,      "fontloader-fonts-demo-vf-1.lua", },
-  { miscdir,      "fontloader-fonts-enc.lua",       },
-  { miscdir,      "fontloader-fonts-ext.lua",       },
-  { miscdir,      "fontloader-fonts.lua",           },
-  { miscdir,      "fontloader-font-lua.lua",        },
-  { miscdir,      "fontloader-fonts-syn.lua",       },
-  { miscdir,      "fontloader-font-tfm.lua",        },
-  { miscdir,      "fontloader-font-otr.lua",        },
-  { miscdir,      "fontloader-font-cff.lua",        },
-  { miscdir,      "fontloader-font-ttf.lua",        },
-  { miscdir,      "fontloader-font-dsp.lua",        },
-  { miscdir,      "fontloader-font-oup.lua",        },
-  { miscdir,      "fontloader-font-otl.lua",        },
-  { miscdir,      "fontloader-font-oto.lua",        },
-  { miscdir,      "fontloader-font-otj.lua",        },
-  { miscdir,      "fontloader-font-ota.lua",        },
-  { miscdir,      "fontloader-font-ots.lua",        },
-  { miscdir,      "fontloader-font-osd.lua",        },
-  { miscdir,      "fontloader-font-ocl.lua",        },
-  { miscdir,      "fontloader-font-otc.lua",        },
-
-  --- lua libraries
-  { miscdir,      "fontloader-languages.lua",       },
-  { miscdir,      "fontloader-l-boolean.lua",       },
-  { miscdir,      "fontloader-l-file.lua",          },
-  { miscdir,      "fontloader-l-function.lua",      },
-  { miscdir,      "fontloader-l-io.lua",            },
-  { miscdir,      "fontloader-l-lpeg.lua",          },
-  { miscdir,      "fontloader-l-lua.lua",           },
-  { miscdir,      "fontloader-l-math.lua",          },
-  { miscdir,      "fontloader-l-string.lua",        },
-  { miscdir,      "fontloader-l-table.lua",         },
-  { miscdir,      "fontloader-math.lua",            },
-  { miscdir,      "fontloader-mplib.lua",           },
-  { miscdir,      "fontloader-preprocessor.lua",    },
-  { miscdir,      "fontloader-swiglib.lua",         },
-  { miscdir,      "fontloader-swiglib-test.lua",    },
-  { miscdir,      "fontloader-util-str.lua",        },
-  { miscdir,      "fontloader-util-fil.lua",        },
-
-} --[[local names]]
-
------------------------------------------------------------------------
--- helpers
------------------------------------------------------------------------
-
-local die = function (...)
-  io.stderr:write "[fatal error]: "
-  io.stderr:write (stringformat (...))
-  io.stderr:write "\naborting.\n"
-  os.exit (1)
-end
-
-local logcmd = "git log -1 \z
-                    --format=\"return {\z
-                                %n  revision  = [[%H]],\z
-                                %n  timestamp = [[%cd]],\z
-                                %n  committer = [[%cn <%ce>]],\z
-                                %n}\" \z
-                    --date=iso"
-local describecmd = "git describe --all"
-
-local readpipe = function (cmd)
-  local chan = iopopen (cmd)
-  if not chan then
-    die ("this script needs to be run inside \z
-          the luaotfload git repository")
-  end
-  local data = chan:read "*all"
-  chan:close ()
-  return data
-end
-
-local git_info = function ()
-  --io.write (logcmd)
-  --io.write "\n"
-  local desc = readpipe (describecmd)
-  if not desc then die "cannot parse git information" end
-  desc = string.fullstrip (desc)
-  local desc = string.explode (desc, "/")[2] or desc
-  if not desc then die "cannot parse sanitized git information" end
-  local data = readpipe (logcmd)
-  if data and type (data) == "string" and data ~= "" then
-    data = load (data)
-    if not data then
-      die "cannot parse git information"
-    end
-    data = data ()
-    data.description = desc
-    return data
-  end
-  die "cannot read from pipe"
-end
-
------------------------------------------------------------------------
--- functionality
------------------------------------------------------------------------
-
-local hash_file = function (fname)
-  if not lfs.isfile (fname) then
-    die ("cannot find %s.", fname)
-  end
-  local raw = ioloaddata (fname)
-  if not raw then
-    die ("cannot read from %s.", fname)
-  end
-  return md5sumhexa (raw)
-end
-
-local hash_all
-hash_all = function (list, acc)
-  if acc == nil then
-    local base = table.fastcopy (names)
-    return hash_all (table.append (base, list), { })
-  end
-
-  local finfo = list[#list]
-  list[#list] = nil
-  if finfo then
-    local fpath, fname
-    if type (finfo) == "table" then
-      local d, f = finfo [1], finfo [2]
-      if lfs.isdir (d) then
-        fpath = file.join (d, f)
-      else
-        fpath = f
-      end
-      fname = f
-    else
-      fpath = finfo
-    end
-    if verbose then
-      iowrite "· md5("
-      iowrite (fpath)
-    end
-    local sum = hash_file (fpath)
-    if verbose then
-      iowrite ") = \""
-      iowrite (sum)
-      iowrite "\"\n"
-    end
-    acc[#acc+1] = { fname, sum }
-    return hash_all (list, acc)
-  end
-  return acc
-end
-
-local handle_argv = function (argv)
-  local ret  = { files = { }, loader = nil }
-  local argc = #argv
-  if argc < 1 then return ret end
-  local argoff = 1
-  if argv [1] == "-v" then
-    verbose = true
-    if argc == 1 then return ret end
-    argoff  = 2
-  end
-  local aux aux = function (acc, i)
-    if i > argc then return acc else
-      local cur = argv[i]
-      if type (cur) == "string" then
-        local loader = stringmatch (cur, "--fontloader=(.+)$")
-        if loader then
-          cur = loader
-          acc.loader = file.basename (cur)
-        end
-        if lfs.isfile (cur) then
-          local files = acc.files
-          files[#files + 1] = cur
-        end
-      else
-        die ("file not found: %s", tostring (cur))
-      end
-      return aux (acc, i + 1)
-    end
-  end
-  return aux (ret, argoff)
-end
-
-local add_files
-add_files = function (lst, acc)
-  if lst == nil then return end
-  if acc == nil then return add_files (lst, { }) end
-  local len   = #lst
-  if len == 0 then return acc end
-  local cur   = lst[len]
-  local fname = file.basename (cur)
-  local path  = file.dirname (cur)
-  acc[#acc + 1] = { path, fname }
-  lst[len] = nil
-  return add_files (lst, acc)
-end
-
-local main = function ()
-  local raw_extra   = handle_argv (arg)
-  local cuit_extra  = add_files (raw_extra.files)
-  local hashes      = hash_all (cuit_extra)
-  local notes       = git_info ()
-  notes.loader      = raw_extra.loader
-  local serialized  = table.serialize ({ notes = notes,
-                                         hashes = hashes }, true)
-  local success     = io.savedata (filelist, serialized)
-  if success == false then
-    die ("could not write to %s.", filelist)
-  end
-  return 0
-end
-
-return main ()
-
---- vim:ft=lua:ts=2:et:sw=2

Deleted: trunk/Master/texmf-dist/scripts/luaotfload/mktests
===================================================================
--- trunk/Master/texmf-dist/scripts/luaotfload/mktests	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/scripts/luaotfload/mktests	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,362 +0,0 @@
-#!/usr/bin/env texlua
------------------------------------------------------------------------
---         FILE:  mktests
---        USAGE:  ./mktests 
---  DESCRIPTION:  test the behavior of Luaotfload
--- REQUIREMENTS:  Luatex > 0.76, Luaotfload
---       AUTHOR:  Philipp Gesang (Phg), <phg42.2a at gmail.com>
------------------------------------------------------------------------
---
---===================================================================--
---                               NOTE
---             this is a stub, to be completed long-term
---                        suggestions welcome
---===================================================================--
-
-
-local tests       = { }
-local lpeg        = require "lpeg"
-local lpegmatch   = lpeg.match
-
-config            = { luaotfload = { } }
-luatexbase        = { }
-
-kpse.set_program_name "luatex"
-
-require "lualibs"
-require "luaotfload-basics-gen.lua"
-require "luaotfload-log.lua"
-
-fonts = { names = { } } -- for db; normally provided by the fontloaders
-
-local require_init = { }
-
-local loadmodule = function (name)
-    local v = require ("luaotfload-" .. name)
-    if v then
-        local mod = { }
-        local tv  = type (v)
-        if tv == "table" then
-            mod.name = name
-            mod.init = v.init
-            require_init [#require_init + 1] = mod
-        elseif tv == "function" then
-            mod.name = name
-            mod.init = v
-            require_init [#require_init + 1] = mod
-        end
-    end
-end
-
-require "alt_getopt"
-
-loadmodule "log.lua"       --- this populates the luaotfload.log.* namespace
-loadmodule "parsers"       --- fonts.conf, configuration, and request syntax
-loadmodule "configuration" --- configuration file handling
-loadmodule "database"
-loadmodule "resolvers"     --- Font lookup
-
-do --- init_modules
-    --- NB we don’t command the logger at this point.
-    local todo = #require_init
-    local ret  = true
-    for i = 1, todo do
-        local mod  = require_init[i]
-        local name = mod.name
-        local init = mod.init
-        if type (init) ~= "function" then
-            error ("luaotfload broken; module "
-                   .. name .. " missing initializers!")
-        end
-        local v = mod.init ()
-        if v == true then
-            --- evaluated well
-        elseif type (v) == "table" then
-            luaotfload[name] = v
-        else
-            error ("luaotfload broken; initialization of module "
-                   .. name .. " returned " .. tostring (v) .. ".")
-            return false
-        end
-    end
-end
-
-local names = fonts.names
-
------------------------------------------------------------------------
---- helper functions
------------------------------------------------------------------------
-
-local pprint_resolve = function (input, output, result)
-  texio.write_nl (string.format ("[%s] “%s” -> “%s”",
-                                 result == true and "passed" or "failed",
-                                 input,
-                                 output))
-end
-
-local pprint_result = function (name, failed, total)
-  if failed == 0 then
-    texio.write_nl (string.format ("[%s] all %d passed", name, total))
-  else
-    texio.write_nl (string.format ("[%s] %d of %d failed",
-                                   name,
-                                   failed,
-                                   total))
-  end
-end
-
-local pprint_spec = function (spec)
-  return string.format ("%s/%s*%.2fpt",
-                        spec.specification,
-                        spec.style or "regular",
-                        spec.optsize or 0)
-end
-
------------------------------------------------------------------------
---- parser tests
------------------------------------------------------------------------
-
-local test_config_input = [==[
-
-
-[foo]
-bar = baz
-xyzzy = no
-buzz
-
-[lavernica "brutalitops"]
-# It’s a locomotive that runs on us.
-  laan-ev = zip zop zooey   ; jib-jab
-Crouton = "Fibrosis \"\\ # "
-
-]==]
-
-local test_config_output = {
-  { section = { title = "foo" },
-    variables = { bar = "baz",
-                  xyzzy = false,
-                  buzz = true } },
-  { section = { title = "lavernica",
-                subtitle = "brutalitops" },
-    variables = { ["laan-ev"] = "zip zop zooey",
-                  crouton = "Fibrosis \"\\ # " } }
-}
-
-local parse_config = function ()
-  local parser = luaotfload.parsers.config
-  local result = lpegmatch (parser, test_config_input)
-  --- compare values recursively
-  local aux aux = function (t1, t2)
-    --- cheaply non-tail recursive
-    local k1 = table.keys (t1)
-    local k2 = table.keys (t2)
-    if #k1 ~= #k2 then
-      return false
-    end
-    for i = 1, #k1 do
-      local k  = k1[i]
-      local v1 = t1[k]
-      local v2 = t2[k]
-      if type (v1) == "table" then
-        if type (v2) ~= "table" or not aux (v1, v2) then
-          return false
-        end
-      elseif v1 ~= v2 then
-        return false
-      end
-    end
-    return true
-  end
-  return aux (result, test_config_output) and 0 or 1, 1
-end
-
-tests["parse_config"] = parse_config
-
------------------------------------------------------------------------
---- font tests
------------------------------------------------------------------------
-
---- test sets
-
-local infer_regular_style = {
-  --- inferring which one is the correct style for “regular”; can be
-  --- obscured by synonyms like “book” etc.
-  { "Iwona",                "Iwona-Regular.otf"         }, -- trivial case
-  { "DejaVu Serif",         "DejaVuSerif.ttf"           },
-  { "DejaVu Sans",          "DejaVuSans.ttf"            },
-  { "Adobe Garamond Pro",   "agaramondpro_regular.otf"  },
-  { "Garamond Premier Pro", "GaramondPremrPro.otf"      },
-  { "CMU Serif",            "cmunrm.otf"                },
-  { "CMU Sans Serif",       "cmunss.otf"                },
-  { "Minion Pro",           "MinionPro-Regular.otf"     },
-  --- Below test will succeed only if we match for the
-  --- splainname (= sanitized tfmdata.fullname) field
-  --- explicitly.
-  { "Minion Pro Italic",    "MinionPro-It.otf"          },
-}
-
-local choose_optical_size = {
-  { { name = "Latin Modern Roman", optsize =  1 }, "lmroman5-regular.otf"        },
-  { { name = "Latin Modern Roman", optsize = 10 }, "lmroman10-regular.otf"       },
-  { { name = "Latin Modern Roman", optsize = 12 }, "lmroman12-regular.otf"       },
-  { { name = "Latin Modern Roman", optsize = 42 }, "lmroman17-regular.otf"       },
-  { { name = "EB Garamond", optsize =  1 }, "EBGaramond08-Regular.otf"           },
-  { { name = "EB Garamond", optsize =  8 }, "EBGaramond08-Regular.otf"           },
-  { { name = "EB Garamond", optsize = 12 }, "EBGaramond12-Regular.otf"           },
-  { { name = "EB Garamond", optsize = 42 }, "EBGaramond12-Regular.otf"           },
-  { { name = "Garamond Premier Pro", optsize =  1 }, "GaramondPremrPro-Capt.otf" },
-  { { name = "Garamond Premier Pro", optsize = 10 }, "GaramondPremrPro.otf"      },
-  { { name = "Garamond Premier Pro", optsize = 15 }, "GaramondPremrPro-Subh.otf" },
-  { { name = "Garamond Premier Pro", optsize = 42 }, "GaramondPremrPro-Disp.otf" },
-}
-
-local choose_style = {
-  { { name = "DejaVu Sans", style = "regular"    }, "DejaVuSans.ttf"                       },
-  { { name = "DejaVu Sans", style = "italic"     }, "DejaVuSans-Oblique.ttf"               },
-  { { name = "DejaVu Sans", style = "bold"       }, "DejaVuSans-Bold.ttf"                  },
-  { { name = "DejaVu Sans", style = "bolditalic" }, "DejaVuSans-BoldOblique.ttf"           },
-  { { name = "Linux Libertine O", style = "regular"    }, "LinLibertine_R.otf"             },
-  { { name = "Linux Libertine O", style = "italic"     }, "LinLibertine_RI.otf"            },
-  { { name = "Linux Libertine O", style = "bold"       }, "LinLibertine_RB.otf"            },
-  { { name = "Linux Libertine O", style = "bolditalic" }, "LinLibertine_RBI.otf"           },
-  { { name = "Liberation Serif", style = "regular"    }, "LiberationSerif-Regular.ttf"     },
-  { { name = "Liberation Serif", style = "italic"     }, "LiberationSerif-Italic.ttf"      },
-  { { name = "Liberation Serif", style = "bold"       }, "LiberationSerif-Bold.ttf"        },
-  { { name = "Liberation Serif", style = "bolditalic" }, "LiberationSerif-BoldItalic.ttf"  },
-  { { name = "CMU Sans Serif", style = "regular"    }, "cmunss.otf"   }, -- no “regular” but “medium”
-  { { name = "CMU Sans Serif", style = "italic"     }, "cmunsi.otf"   }, -- no “italic” but “oblique”
-  { { name = "CMU Sans Serif", style = "bold"       }, "cmunsx.otf"   },
-  { { name = "CMU Sans Serif", style = "bolditalic" }, "cmunso.otf"   },
-  --[[--
-    Minion Pro Italic is exceptionally weird regarding identifiers in
-    that the postscript fontname and both info.fontname and
-    info.fullname are given as “minionproit”. Now its english fullname
-    (field 18) is “minionproital”. Only the value “fullname” in the root of
-    the tfmdata structure (not the one returned by fontloader.info()!)
-    accurately yields “Minion Pro Italic”.
-
-    To complete the picture, the file naming isn’t very consistent either:
-    we find the suffixes “Regular” and “Bold”, but “It” and “BoldIt”. What
-    the hell were the designers smoking?
-
-    Also, the full Minion Pro set comes with different optical sizes which
-    for monetary reasons cannot considered here.
-  --]]--
-  { { name = "Minion Pro", style = "regular"    }, "MinionPro-Regular.otf"  },
-  { { name = "Minion Pro", style = "italic"     }, "MinionPro-It.otf"       },
-  { { name = "Minion Pro", style = "bold"       }, "MinionPro-Bold.otf"     },
-  { { name = "Minion Pro", style = "bolditalic" }, "MinionPro-BoldIt.otf"   },
-}
-
---- this needs a database built with --formats=+pfa,pfb,afm
-
-local resolve_t1_font = {
-  { { name = "URW Gothic L",          style = "regular"    }, "a010013l.pfb"  }, --> “book”
---  { { name = "URW Gothic L",          style = "italic"     }, "a010033l.pfb"  }, --> “book oblique”
---  { { name = "URW Gothic L",          style = "bold"       }, "a010015l.pfb"  }, --> “demi”
---  { { name = "URW Gothic L",          style = "bolditalic" }, "a010035l.pfb"  }, --> “demi oblique”
-  { { name = "Century Schoolbook L",  style = "regular"    }, "c059013l.pfb"  },
-  { { name = "Century Schoolbook L",  style = "italic"     }, "c059033l.pfb"  },
-  { { name = "Century Schoolbook L",  style = "bold"       }, "c059016l.pfb"  },
-  { { name = "Century Schoolbook L",  style = "bolditalic" }, "c059036l.pfb"  },
-  { { name = "Nimbus Roman No9 L",    style = "regular"    }, "n021003l.pfb"  },
-  { { name = "Nimbus Roman No9 L",    style = "italic"     }, "n021023l.pfb"  },
-  { { name = "Nimbus Roman No9 L",    style = "bold"       }, "n021004l.pfb"  }, --- medium, actually
-  { { name = "Nimbus Roman No9 L",    style = "bolditalic" }, "n021024l.pfb"  },
-}
-
-local translate_style = {
-  regular     = "r",
-  italic      = "i",
-  bold        = "b",
-  bolditalic  = "bi",
-}
-
-local font_name_tests = {
-  infer_regular_style,
-  choose_optical_size,
-  choose_style,
-  resolve_t1_font,
-}
-
-local default_spec = {
-  name          = false,
-  lookup        = "name",
-  specification = false,
-  optsize       = 0,
-}
-
-local resolve_font_name = function ()
-  local failed, total = 0, 0
-  for nset = 1, #font_name_tests do
-    local set = font_name_tests[nset]
-
-    for ntest = 1, #set do
-      local test = set[ntest]
-      local input, output = test[1], test[2]
-
-      if type (input) == "string" then
-        local input_spec = table.copy (default_spec)
-        input_spec.name = input
-        input_spec.specification = input_spec.lookup .. ":" .. input
-        local result = fonts.names.lookup_font_name (input_spec) == output
-        total = total + 1
-        if not result then
-          failed = failed + 1
-        end
-        pprint_resolve (input, output, result)
-
-      else
-        local input_spec, output = test[1], test[2]
-        input_spec.specification = (input_spec.lookup
-                                    or default_spec.lookup)
-                                .. ":" .. input_spec.name
-        input_spec.optsize = input_spec.optsize or default_spec.optsize
-        input_spec.style   = translate_style [input_spec.style]
-        local result = fonts.names.lookup_font_name (input_spec) == output
-        total = total + 1
-        if not result then
-          failed = failed + 1
-        end
-        pprint_resolve (pprint_spec (input_spec), output, result)
-      end
-
-    end
-  end
-  return failed, total
-end
-
-tests ["resolve_font_name"] = resolve_font_name
-
-
------------------------------------------------------------------------
---- runner
------------------------------------------------------------------------
-
-local main = function ()
-  local failed, total = 0, 0
-  config.actions.apply_defaults ()
-  for name, test in next, tests do
-    texio.write_nl ("[" .. name .. "]")
-    local newfailed, newtotal = test ()
-    total  = total + 1
-    pprint_result (name, newfailed, newtotal)
-    failed = failed + newfailed
-    total  = total  + newtotal
-  end
-
-  if failed == 0 then
-    texio.write_nl (string.format ("[report] all %d tests passed.", total))
-  else
-    texio.write_nl (string.format ("[report] %d of %d tests failed (%d %%).",
-                                   failed,
-                                   total,
-                                   failed / total * 100))
-  end
-  texio.write_nl ""
-  os.exit (0)
-end
-
-return main ()
-
---- vim:ft=lua:ts=2:et:sw=2

Deleted: trunk/Master/texmf-dist/source/luatex/luaotfload/Makefile
===================================================================
--- trunk/Master/texmf-dist/source/luatex/luaotfload/Makefile	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/source/luatex/luaotfload/Makefile	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,263 +0,0 @@
-# Makefile for luaotfload
-
-NAME		= luaotfload
-
-DOCSRCDIR	= ./doc
-SCRIPTSRCDIR	= ./scripts
-SRCSRCDIR	= ./src
-FONTLOADERDIR	= $(SRCSRCDIR)/fontloader/runtime
-FONTLOADERSRCDIR= $(SRCSRCDIR)/fontloader/misc
-PACKAGEDIR	= $(SRCSRCDIR)/fontloader
-BUILDDIR	= ./build
-MISCDIR		= ./misc
-
-SRC		= $(wildcard $(SRCSRCDIR)/luaotfload-*.lua)
-SRC		+= $(wildcard $(FONTLOADERDIR)/*.lua)
-SRC		+= $(SRCSRCDIR)/luaotfload.sty
-SRC		+= $(MISCDIR)/luaotfload-blacklist.cnf
-
-VGND		= $(MISCDIR)/valgrind-kpse-suppression.sup
-CONFDEMO	= $(MISCDIR)/luaotfload.conf.example
-
-GLYPHSCRIPT	= $(SCRIPTSRCDIR)/mkglyphlist
-CHARSCRIPT	= $(SCRIPTSRCDIR)/mkcharacters
-STATUSSCRIPT	= $(SCRIPTSRCDIR)/mkstatus
-IMPORTSCRIPT	= $(SCRIPTSRCDIR)/mkimport
-TESTSCRIPT	= $(SCRIPTSRCDIR)/mktests
-
-GLYPHSOURCE	= $(BUILDDIR)/glyphlist.txt
-
-RESOURCESCRIPTS = $(GLYPHSCRIPT) $(CHARSCRIPT) $(STATUSSCRIPT)
-RESOURCESCRIPTS+= $(IMPORTSCRIPT) $(TESTSCRIPT)
-
-TOOLNAME	= luaotfload-tool
-TOOL		= $(SRCSRCDIR)/$(TOOLNAME).lua
-
-CONFNAME	= luaotfload.conf
-
-GRAPH		= filegraph
-DOCSRC		= $(addprefix $(DOCSRCDIR)/$(NAME), -main.tex -latex.tex)
-LOADERSRC	= $(wildcard $(FONTLOADERSRCDIR)/*.lua)
-LOADERSRC	+= $(wildcard $(FONTLOADERSRCDIR)/*.tex)
-GRAPHSRC	= $(DOCSRCDIR)/$(GRAPH).dot
-MANSRC		= $(DOCSRCDIR)/$(TOOLNAME).rst $(DOCSRCDIR)/$(CONFNAME).rst
-
-DOCPDF		= $(DOCSRCDIR)/$(NAME).pdf
-DOTPDF		= $(DOCSRCDIR)/$(GRAPH).pdf
-TOOLMAN 	= $(DOCSRCDIR)/$(TOOLNAME).1
-CONFMAN		= $(DOCSRCDIR)/$(CONFNAME).5
-MANPAGES	= $(TOOLMAN) $(CONFMAN)
-
-DOCS		= $(DOCPDF) $(DOTPDF) $(MANPAGES)
-
-# Files grouped by generation mode
-GLYPHS		= $(BUILDDIR)/$(NAME)-glyphlist.lua
-CHARS		= $(BUILDDIR)/$(NAME)-characters.lua
-STATUS		= $(BUILDDIR)/$(NAME)-status.lua
-LOADER		= $(BUILDDIR)/fontloader-$(shell date +%F).lua
-RESOURCES	= $(GLYPHS) $(CHARS) $(LOADER) $(STATUS)
-SOURCE		= $(DOCSRC) $(LOADERSRC) $(MANSRC)
-SOURCE		+= $(SRC) README COPYING Makefile NEWS $(RESOURCESCRIPTS)
-
-# Files grouped by installation location
-SCRIPTSTATUS	= $(TOOL) $(RESOURCESCRIPTS)
-RUNSTATUS	= $(filter-out $(SCRIPTSTATUS),$(SRC))
-DOCSTATUS	= $(DOCPDF) $(DOTPDF) README NEWS COPYING
-SRCSTATUS	= $(DOCSRC) $(MANSRC) $(GRAPHSRC) Makefile
-
-# The following definitions should be equivalent
-# ALL_STATUS = $(RUNSTATUS) $(DOCSTATUS) $(SRCSTATUS)
-ALL_STATUS 	= $(RESOURCES) $(SOURCE)
-
-# Installation locations
-FORMAT 		= luatex
-SCRIPTDIR	= $(TEXMFROOT)/scripts/$(NAME)
-RUNDIR		= $(TEXMFROOT)/tex/$(FORMAT)/$(NAME)
-DOCDIR		= $(TEXMFROOT)/doc/$(FORMAT)/$(NAME)
-MAN1DIR		= $(TEXMFROOT)/doc/man/man1/
-MAN5DIR		= $(TEXMFROOT)/doc/man/man5/
-SRCDIR		= $(TEXMFROOT)/source/$(FORMAT)/$(NAME)
-TEXMFROOT	= $(shell kpsewhich --var-value TEXMFHOME)
-
-# CTAN-friendly subdirectory for packaging
-DISTDIR		= $(BUILDDIR)/$(NAME)
-
-CTAN_ZIPFILE	= $(NAME).zip
-CTAN_ZIPSIG	= $(BUILDDIR)/$(CTAN_ZIPFILE).asc
-TDS_ZIPFILE	= $(NAME).tds.zip
-CTAN_ZIP	= $(BUILDDIR)/$(CTAN_ZIPFILE)
-TDS_ZIP		= $(BUILDDIR)/$(TDS_ZIPFILE)
-ZIPS		= $(CTAN_ZIP) $(TDS_ZIP)
-
-LUA		= texlua
-
-## For now the $(BUILDDIR) is hardcoded in the scripts
-## but we might just as well pass it to them by as environment
-## variables.
-DO_GLYPHS	= $(LUA) $(GLYPHSCRIPT) > /dev/null
-DO_CHARS	= $(LUA) $(CHARSCRIPT)  > /dev/null
-DO_STATUS	= $(LUA) $(STATUSSCRIPT) --fontloader=$(LOADER) >/dev/null
-DO_IMPORT	= $(LUA) $(IMPORTSCRIPT) import >/dev/null
-DO_PACKAGE	= $(LUA) $(IMPORTSCRIPT) package $(LOADER) >/dev/null
-
-define check-lua-files
- at echo validating syntax
- at for f in $$(find . -name '*.lua') ; do	\
-  echo -n checking $$f ...;		\
-  if texluac -p $$f &>/dev/null; then	\
-    echo -e " \e[1;32mgood.\e[m";	\
-  else					\
-    echo -e " \e[1;31mBAD.\e[m";	\
-    exit 1;				\
-  fi;					\
-done
-endef
-
-show: showtargets
-check:
-	$(check-lua-files)
-
-all: ctan
-builddir: $(BUILDDIR)
-resources: $(RESOURCES)
-chars: $(CHARS)
-status: $(STATUS)
-package: loader
-loader: $(LOADER)
-ctan: $(CTAN_ZIP)
-tds: $(TDS_ZIP)
-import:
-	$(DO_IMPORT)
-
-graph: $(DOTPDF)
-doc: $(DOCS)
-pdf: $(DOCPDF)
-manual: $(MANPAGES)
-
-$(DOTPDF):
-	@$(MAKE) -C $(DOCSRCDIR) graph
-
-$(DOCPDF):
-	@$(MAKE) -C $(DOCSRCDIR) doc
-
-$(MANPAGES):
-	@$(MAKE) -C $(DOCSRCDIR) manuals
-
-$(GLYPHS): builddir
-	$(DO_GLYPHS)
-
-$(CHARS): builddir
-	$(DO_CHARS)
-
-$(STATUS): builddir loader
-	$(DO_STATUS)
-
-$(LOADER): builddir
-	$(DO_PACKAGE)
-
-$(BUILDDIR): /dev/null
-	mkdir -p $(BUILDDIR)
-
-define make-ctandir
-@$(RM) -rf -- $(DISTDIR)
- at mkdir -p $(DISTDIR) && cp $(RESOURCES) $(DOCPDF) $(VGND) $(CONFDEMO) $(SOURCE) $(DISTDIR)
-endef
-
-$(CTAN_ZIP): $(DOCS) $(SOURCE) $(TDS_ZIP)
-	@echo "Making $@ for CTAN upload."
-	@$(RM) -- $@
-	$(make-ctandir)
-	@cd $(BUILDDIR) && zip -r -9 $(CTAN_ZIPFILE) $(TDS_ZIPFILE) $(NAME) >/dev/null
-
-$(CTAN_ZIPSIG): $(CTAN_ZIP)
-	@echo "Signing package $(CTAN_ZIP)"
-	@$(RM) -- $@
-	@gpg --batch --armor --detach-sign "$(CTAN_ZIP)"
-
-define run-install-doc
- at mkdir -p $(DOCDIR)  && cp -- $(DOCSTATUS) $(VGND) $(CONFDEMO) $(DOCDIR)
- at mkdir -p $(SRCDIR)  && cp -- $(SRCSTATUS) $(SRCDIR)
- at mkdir -p $(MAN1DIR) && cp -- $(TOOLMAN) $(MAN1DIR)
- at mkdir -p $(MAN5DIR) && cp -- $(CONFMAN) $(MAN5DIR)
-endef
-
-define run-install
- at mkdir -p $(SCRIPTDIR) && cp -- $(SCRIPTSTATUS) $(SCRIPTDIR)
- at mkdir -p $(RUNDIR)    && cp -- $(RESOURCES) $(RUNSTATUS) $(RUNDIR)
- at mkdir -p $(RUNDIR)    && cp -- $(LOADERSRC) $(RUNDIR)
-endef
-
-$(TDS_ZIP): TEXMFROOT=./tmp-texmf
-$(TDS_ZIP): $(DOCS) $(ALL_STATUS) check
-	@echo "Making TDS-ready archive $@."
-	@$(RM) -- $@
-	$(run-install-doc)
-	$(run-install)
-	@cd $(TEXMFROOT) && zip -9 ../$@ -r . >/dev/null
-	@$(RM) -r -- $(TEXMFROOT)
-
-sign: $(CTAN_ZIPSIG)
-
-.PHONY: package install manifest clean mrproper show showtargets
-.PHONY: check import news tds ctan sign package loader
-
-ifndef DESTDIR
-install:
-	$(error "in order to install you need to provide $$DESTDIR")
-else
-install: $(TDS_ZIP)
-	$(info installing to destination “$(DESTDIR)”)
-	install -dm755 "$(DESTDIR)"
-	unzip "$(TDS_ZIP)" -d "$(DESTDIR)"
-endif
-
-manifest:
-	@echo "Source files:"
-	@for f in $(SOURCE); do echo $$f; done
-	@echo ""
-	@echo "Derived files:"
-	@for f in $(GENERATED); do echo $$f; done
-
-CLEANEXTS	= log aux toc idx ind ilg out
-CLEANME		= $(foreach ext,$(CLEANEXTS),$(wildcard *.$(ext)))
-CLEANME		+= $(foreach ext,$(CLEANEXTS),$(wildcard $(BUILDDIR)/*$(ext)))
-
-clean:
-	$(MAKE) -C $(DOCSRCDIR) $@
-	@$(RM) -- $(CLEANME)
-
-mrproper: clean
-	$(MAKE) -C $(DOCSRCDIR) $@
-	@$(RM) -- $(GENERATED) $(ZIPS) $(GLYPHSOURCE)
-	@$(RM) -r -- $(BUILDDIR)
-
-###############################################################################
-showtargets:
-	@echo "Available targets:"
-	@echo
-	@echo "       check       check Lua files for syntax errors"
-	@echo
-	@echo "       doc         compile PDF documentation"
-	@echo "       resources   generate resource files (chars, glyphs)"
-	@echo
-	@echo "       pdf         build luaotfload.pdf"
-	@echo "       manual      crate manpages for luaotfload-tool(1) and"
-	@echo "                   luaotfload.conf(5) (requires Docutils)"
-	@echo "       graph       generate file graph (requires GraphViz)"
-	@echo
-	@echo "       loader      merge fontloader"
-	@echo "       chars       import char-def.lua as luaotfload-characters.lua"
-	@echo "       status      create repository info (luaotfload-status.lua)"
-	@echo
-	@echo "       import      grab files from upstream"
-	@echo "       package     package fontloader"
-	@echo
-	@echo "       tds         package a zipball according to the TDS"
-	@echo "       ctan        package a zipball for uploading to CTAN"
-	@echo "       sign        sign zipball"
-	@echo
-	@echo "       clean       cleanup side-effects"
-	@echo "       mrproper    cleanup side-effects as well as make targets"
-	@echo
-
-# vim:noexpandtab:tabstop=8:shiftwidth=2

Deleted: trunk/Master/texmf-dist/source/luatex/luaotfload/filegraph.dot
===================================================================
--- trunk/Master/texmf-dist/source/luatex/luaotfload/filegraph.dot	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/source/luatex/luaotfload/filegraph.dot	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,396 +0,0 @@
-strict digraph luaotfload_files { //looks weird with circo ...
-    compound       = true;
-
-//  label          = "Schematic of the files included in Luaotfload.";
-//  labelloc       = "b";
-
-    fontsize       = "14.4";
-    labelfontname  = "Iwona Medium Regular";
-    fontname       = "Iwona Light Regular";
-    size           = "21cm";
-
-    rankdir        = LR;
-    ranksep        = 0.618;
-    nodesep        = 1.618;
-
-    edge [
-        arrowhead = onormal,
-        fontname  = "Iwona Cond Regular",
-        penwidth  = 1.0,
-    ];
-    node [
-        //penwidth = 0.7,
-        fontname = "Liberation Mono",
-        fontsize = 12,
-    ];
-
-/* ····································································
- * file structure
- * ································································· */
-    fontdbutil  -> font_names   [label="--update",
-                                 style=dashed]
-
-    luaotfload -> merged_lua_libs     [style=solid]
-    luaotfload -> luaotfload_init     [label="main()",   style=solid]
-    luaotfload -> luaotfload_libs     [label="main()",   style=solid]
-
-    fontloader        -> merged_luatex_fonts [label="merged",
-                                              style=dotted,
-                                              lhead=cluster_merged]
-    fontloader        -> merged_context_libs [label="merged",
-                                              style=dotted,
-                                              lhead=cluster_merged]
-
-    luaotfload_init -> luaotfload_log        [label="init_early()", style=solid]
-    luaotfload_init -> luaotfload_basics_gen [label="init_early()", style=solid]
-    luaotfload_init -> fontloader            [label="init_main()",  style=solid]
-
-    luaotfload_init -> merged_luatex_fonts [label="unmerged", style=solid]
-    luaotfload_init -> merged_context_libs [label="unmerged", style=solid]
-
-    merged_luatex_fonts -> font_age [label="luatex-fonts-enc.lua",
-                                     ltail=cluster_merged]
-
-    fontdbutil -> fontdbutil_diagnostics [label="--diagnose"]
-    fontdbutil -> status [label="version information"]
-
-    mkimport -> fontloader [label="merges", style=dashed]
-
-    merged_luatex_fonts -> characters [label="luaotfload-auxiliary.lua",
-                                       ltail=cluster_merged]
-
-    luaotfload_libs -> font_names         [label="luaotfload-database.lua"]
-    luaotfload_libs -> otfl_blacklist_cnf [label="luaotfload-database.lua"]
-
-
-    mkstatus    -> status     [label="generates from distribution files",
-                               style=dashed]
-
-    mkglyphlist -> font_age     [label="generates from glyphlist.txt",
-                                 style=dashed]
-
-    mkcharacters -> characters     [label="generates from Context’s char-def.lua",
-                                    style=dashed]
-
-    fontdbutil_diagnostics -> status [label="hash files"]
-
-    mkimport -> merged_luatex_fonts [label="pulls", style=dashed, constraint=no];
-    mkimport -> merged_context_libs [label="pulls", style=dashed, constraint=no];
-
-    subgraph { rank = same;
-               fontdbutil;
-               luaotfload }
-
-    subgraph cluster_scripts {
-        node [style=filled, color=white];
-        style     = "filled,rounded";
-        color     = "#44000011:#CCCCCC77";
-        //nodesep   = "3.0";
-        rank      = same;
-        label     = "Standalone scripts";
-        gradientangle=90;
-        mkcharacters;
-        mkglyphlist;
-        mkimport;
-        mktest;
-        mkstatus;
-    }
-
-/* ····································································
- * main files
- * ································································· */
-
-    fontdbutil        [label  = "luaotfload-tool.lua",
-                       shape  = rect,
-                       width  = "3.2cm",
-                       height = "1.2cm",
-                       color  = "#01012222",
-                       style  = "filled,rounded",
-                       penwidth=2]
-
-    fontdbutil_diagnostics [label  = "luaotfload-diagnostics.lua",
-                            shape  = rect,
-                            width  = "3.2cm",
-                            height = "1.2cm",
-                            color  = "#01012222",
-                            style  = "filled,rounded",
-                            penwidth=2]
-
-    mktest           [label  = "mktest",
-                       shape  = rect,
-                       width  = "3.2cm",
-                       height = "0.618cm",
-                       color  = "#FFFFFF66",
-                       style  = "filled,rounded",
-                       penwidth=2]
-
-    mkimport          [label  = "mkimport",
-                       shape  = rect,
-                       width  = "3.2cm",
-                       height = "0.618cm",
-                       color  = "#FFFFFF66",
-                       style  = "filled,rounded",
-                       penwidth=2]
-
-    mkstatus          [label  = "mkstatus",
-                       shape  = rect,
-                       width  = "3.2cm",
-                       height = "0.618cm",
-                       color  = "#FFFFFF66",
-                       style  = "filled,rounded",
-                       penwidth=2]
-
-    mkglyphlist       [label  = "mkglyphlist",
-                       shape  = rect,
-                       width  = "3.2cm",
-                       height = "0.618cm",
-                       color  = "#FFFFFF66",
-                       style  = "filled,rounded",
-                       penwidth=2]
-
-    mkcharacters      [label  = "mkcharacters",
-                       shape  = rect,
-                       width  = "3.2cm",
-                       height = "0.618cm",
-                       color  = "#FFFFFF66",
-                       style  = "filled,rounded",
-                       penwidth=2]
-
-    luaotfload        [label  = "luaotfload-main.lua",
-                       shape  = rect,
-                       width  = "3.2cm",
-                       height = "1.2cm",
-                       color  = "#01012222",
-                       style  = "filled,rounded",
-                       penwidth=2]
-    /*
-     *otfl_fonts        [label = "luaotfload-fonts.lua",
-     *                   shape = rect,
-     *                   width  = "3.2cm",
-     *                   height = "1.2cm",
-     *                   color  = "#01012222",
-     *                   style  = "filled,rounded",
-     *                   penwidth=2]
-     */
-    luaotfload_init       [label = "luaotfload-init.lua",
-                           shape = rect,
-                           width  = "3.2cm",
-                           height = "1.2cm",
-                           color  = "#44440122",
-                           style  = "filled,rounded",
-                           penwidth=2]
-
-    luaotfload_log        [label = "luaotfload-log.lua",
-                           shape = rect,
-                           width  = "3.2cm",
-                           height = "1.2cm",
-                           color  = "#44440122",
-                           style  = "filled,rounded",
-                           penwidth=2]
-
-    luaotfload_basics_gen [label = "fontloader-basics-gen.lua",
-                           shape = rect,
-                           width  = "3.2cm",
-                           height = "1.2cm",
-                           color  = "#FFFFFF66",
-                           style  = "filled,rounded",
-                           penwidth=2]
-
-    fontloader            [label = "fontloader-YY-MM-DD.lua",
-                           shape = rect,
-                           width  = "3.2cm",
-                           height = "1.2cm",
-                           color  = "#FFFFFF66",
-                           style  = "filled,rounded",
-                           penwidth=2]
-
-/* ····································································
- * luaotfload files
- * ································································· */
-
-    characters [style      = "filled,dashed",
-                shape      = rect,
-                width      = "3.2cm",
-                fillcolor  = "#01012222",
-                color      = grey40,
-                style      = "filled,dotted,rounded",
-                label      = "luaotfload-characters.lua"]
-
-    font_age [style      = "filled,dashed",
-              shape      = rect,
-              width      = "3.2cm",
-              fillcolor  = "#01012222",
-              color      = grey40,
-              style      = "filled,dotted,rounded",
-              label      = "luaotfload-glyphlist.lua"]
-
-    font_names [style      = "filled,dashed",
-                shape      = rect,
-                width      = "3.2cm",
-                fillcolor  = "#01012222",
-                color      = grey40,
-                style      = "filled,dotted,rounded",
-                label      = "luaotfload-names.lua.gz\nluaotfload-names.luc"]
-
-    status [style      = "filled,dashed",
-            shape      = rect,
-            width      = "3.2cm",
-            fillcolor  = "#01012222",
-            color      = grey40,
-            style      = "filled,dotted,rounded",
-            label      = "luaotfload-status.lua"]
-
-    otfl_blacklist_cnf [style      = "filled,dashed",
-                        shape      = rect,
-                        width      = "3.2cm",
-                        fillcolor  = "#01012222",
-                        color      = grey40,
-                        style      = "filled,dotted,rounded",
-                        label      = "luaotfload-blacklist.cnf"]
-
-    luaotfload_libs [
-        shape      = box,
-        style      = "filled,rounded",
-        color      = "grey90",
-        fontsize   = 10,
-        label      = <
-            <table cellborder="0" bgcolor="#FFFFFFAA">
-                <th> <td colspan="2"> <font point-size="12" face="Iwona Italic">Luaotfload Libraries</font> </td> </th>
-                <tr> <td>luaotfload-auxiliary.lua</td>    <td>luaotfload-features.lua</td>      </tr>
-                <tr> <td>luaotfload-loaders.lua</td>      <td>luaotfload-colors.lua</td>        </tr>
-                <tr> <td>luaotfload-resolvers.lua</td>    <td>luaotfload-letterspace.lua</td>   </tr>
-                <tr> <td>luaotfload-parsers.lua</td>      <td>luaotfload-database.lua</td>      </tr>
-                <tr> <td>luaotfload-configuration.lua</td><td></td>                             </tr>
-            </table>
-        >,
-    ]
-
-/* ····································································
- * merged files
- * ································································· */
-
-   subgraph cluster_merged {
-       node [style=filled, color=white];
-       style     = "filled,rounded";
-       color     = "#912CEE33";
-       //nodesep   = "3.0";
-       rank      = same;
-       label     = "Merged Libraries";
-       gradientangle=0;
-       merged_luatex_fonts;
-       merged_context_libs;
-   }
-
-    fontloader -> merged_luatex_fonts
-    fontloader -> merged_context_libs
-
-   subgraph cluster_fontloader {
-       node [style=filled, color=white];
-       style     = "filled,rounded";
-       color     = "bisque";
-       //nodesep   = "3.0";
-       rank      = same;
-       label     = "Fontloader";
-       gradientangle=0;
-       luaotfload_basics_gen;
-       fontloader;
-   }
-
-    merged_lua_libs [
-        shape      = box,
-        style      = "filled,rounded",
-        color      = "#CCCC1166",
-        fontsize   = 10,
-        fontsize   = 10,
-        label      = <
-            <table border="0">
-                <th> <td colspan="3"> <font point-size="12" face="Iwona Italic">
-                        Lualibs – Lua Libraries from Context</font> </td> </th>
-                <tr> <td>l-lua.lua</td>     <td>l-lpeg.lua</td>    <td>l-function.lua</td>  </tr>
-                <tr> <td>l-string.lua</td>  <td>l-table.lua</td>   <td>l-io.lua</td>        </tr>
-                <tr> <td>l-file.lua</td>    <td>l-boolean.lua</td> <td>l-math.lua</td>      </tr>
-                <tr> <td>util-str.lua</td>  <td>util-fil.lua</td>                           </tr>
-            </table>
-        >,
-    ]
-
-    merged_luatex_fonts [
-        shape      = box,
-        style      = "filled,rounded",
-        color      = "#FFFFFFAA",
-        fontsize   = 10,
-        label      = <
-            <table border="0">
-                <th> <td colspan="2"> <font point-size="12" face="Iwona Italic">Font Loader (LuaTeX-Fonts)</font> </td> </th>
-                <tr>
-                    <td>luatex-basics-nod.lua</td>
-                    <td>luatex-basics-chr.lua</td>
-                </tr>
-                <tr>
-                    <td>luatex-fonts-enc.lua</td>
-                    <td>luatex-fonts-syn.lua</td>
-                </tr>
-                <tr>
-                    <td>luatex-fonts-ext.lua</td>
-                </tr>
-            </table>
-        >,
-    ]
-
-    merged_context_libs [
-        shape      = box,
-        style      = "filled,rounded",
-        color      = "#FFFFFFAA",
-        fontsize   = 10,
-        label      = <
-            <table border="0">
-                <th> <td colspan="3"> <font point-size="12" face="Iwona Italic"> Font and Node Libraries from Context </font> </td> </th>
-                <tr>
-                    <td>data-con.lua</td>
-                    <td>font-ini.lua</td>
-                    <td>font-con.lua</td>
-                </tr>
-                <tr>
-                    <td>font-cid.lua</td>
-                    <td>font-map.lua</td>
-                    <td>font-tfm.lua</td>
-                </tr>
-                <tr>
-                    <td>font-one.lua</td>
-                    <td>font-afk.lua</td>
-                    <td>font-oti.lua</td>
-                </tr>
-                <tr>
-                    <td>font-otr.lua</td>
-                    <td>font-cff.lua</td>
-                    <td>font-ttf.lua</td>
-                </tr>
-                <tr>
-                    <td>font-dsp.lua</td>
-                    <td>font-oup.lua</td>
-                    <td>font-otl.lua</td>
-                </tr>
-                <tr>
-                    <td>font-oto.lua</td>
-                    <td>font-otj.lua</td>
-                    <td>font-ota.lua</td>
-                </tr>
-                <tr>
-                    <td>font-ots.lua</td>
-                    <td>font-osd.lua</td>
-                    <td>font-lua.lua</td>
-                </tr>
-                <tr>
-                    <td>font-def.lua</td>
-                    <td>font-xtx.lua</td>
-                    <td>font-gbn.lua</td>
-                </tr>
-                <tr>
-                    <td>font-ocl.lua</td>
-                </tr>
-            </table>
-        >,
-    ]
-}
-
-// vim:ft=dot:sw=4:ts=4:expandtab

Added: trunk/Master/texmf-dist/source/luatex/luaotfload/fontloader-reference-load-order.lua
===================================================================
--- trunk/Master/texmf-dist/source/luatex/luaotfload/fontloader-reference-load-order.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/source/luatex/luaotfload/fontloader-reference-load-order.lua	2018-09-26 20:50:34 UTC (rev 48771)
@@ -0,0 +1,350 @@
+if not modules then modules = { } end modules ['luatex-fonts'] = {
+    version   = 1.001,
+    comment   = "companion to luatex-fonts.tex",
+    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+    copyright = "PRAGMA ADE / ConTeXt Development Team",
+    license   = "see context related readme files"
+}
+
+-- A merged file is generated with:
+--
+--   mtxrun --script package --merge --stripcontext luatex-fonts.lua
+--
+-- A needed resource file is made by:
+--
+--   mtxrun --script context luatex-basics-prepare.tex
+--
+-- A font (generic) database is created with:
+--
+--   mtxrun --script font --reload --simple
+
+-- The following code isolates the generic context code from already defined or to be defined
+-- namespaces. This is the reference loader for plain tex. This generic code is also used in
+-- luaotfload which is a low level lualatex opentype font loader but somehow has gotten a bit
+-- too generic name / prefix, originally set up and maintained by Khaled Hosny. Currently that
+-- set of derived files is maintained by a larger team lead by Philipp Gesang so when there are
+-- issues with this code in latex, you can best contact him. It might make sense then to first
+-- check if context has the same issue. We do our best to keep the interface as clean as possible.
+--
+-- The code base is rather stable now, especially if you stay away from the non generic code. All
+-- relevant data is organized in tables within the main table of a font instance. There are a few
+-- places where in context other code is plugged in, but this does not affect the core code. Users
+-- can (given that their macro package provides this option) access the font data (characters,
+-- descriptions, properties, parameters, etc) of this main table. The documentation is part of
+-- context. There is also a manual for the helper libraries (maintained as part of the cld manuals).
+--
+-- Future versions will probably have some more specific context code removed, like tracing and
+-- obscure hooks, so that we have a more efficient version (and less files too). So, don't depend
+-- too much on low level code that is meant for context as it can change without notice. We might
+-- also add more helper code here, but that depends to what extend metatex (sidetrack of context)
+-- evolves into a low level layer (depends on time, as usual).
+
+-- The code here is the same as in context version 2015.09.11 but the rendering in context can be
+-- different from generic. This can be a side effect of additional callbacks, additional features
+-- and interferences between mechanisms between macro packages. We use the rendering in context
+-- and luatex-plain as reference for issues.
+
+utf = utf or unicode.utf8
+
+-- We have some (global) hooks (for latex):
+
+if not non_generic_context then
+    non_generic_context = { }
+end
+
+if not non_generic_context.luatex_fonts then
+    non_generic_context.luatex_fonts = {
+     -- load_before  = nil,
+     -- load_after   = nil,
+     -- skip_loading = nil,
+    }
+end
+
+if not generic_context then
+    generic_context  = { }
+end
+
+if not generic_context.push_namespaces then
+
+    function generic_context.push_namespaces()
+     -- logs.report("system","push namespace")
+        local normalglobal = { }
+        for k, v in next, _G do
+            normalglobal[k] = v
+        end
+        return normalglobal
+    end
+
+    function generic_context.pop_namespaces(normalglobal,isolate)
+        if normalglobal then
+         -- logs.report("system","pop namespace")
+            for k, v in next, _G do
+                if not normalglobal[k] then
+                    generic_context[k] = v
+                    if isolate then
+                        _G[k] = nil
+                    end
+                end
+            end
+            for k, v in next, normalglobal do
+                _G[k] = v
+            end
+            -- just to be sure:
+            setmetatable(generic_context,_G)
+        else
+            logs.report("system","fatal error: invalid pop of generic_context")
+            os.exit()
+        end
+    end
+
+end
+
+local whatever = generic_context.push_namespaces()
+
+-- We keep track of load time by storing the current time. That way we cannot be accused
+-- of slowing down loading too much. Anyhow, there is no reason for this library to perform
+-- slower in any other package as it does in context.
+--
+-- Please don't update to this version without proper testing. It might be that this version
+-- lags behind stock context and the only formal release takes place around tex live code
+-- freeze.
+
+local starttime = os.gettimeofday()
+
+-- As we don't use the context file searching, we need to initialize the kpse library. As the
+-- progname can be anything we will temporary switch to the context namespace if needed. Just
+-- adding the context paths to the path specification is somewhat faster.
+--
+-- Now, with lua 5.2 being used we might create a special ENV for this.
+
+-- kpse.set_program_name("luatex")
+
+-- One can define texio.reporter as alternative terminal/log writer. That's as far
+-- as I want to go with this.
+
+local ctxkpse = nil
+local verbose = true
+
+if not logs or not logs.report then
+    if not logs then
+        logs = { }
+    end
+    function logs.report(c,f,...)
+        local r = texio.reporter or texio.write_nl
+        if f then
+            r(c .. " : " .. string.format(f,...))
+        else
+            r("")
+        end
+    end
+end
+
+local function loadmodule(name,continue)
+    local foundname = kpse.find_file(name,"tex") or ""
+    if not foundname then
+        if not ctxkpse then
+            ctxkpse = kpse.new("luatex","context")
+        end
+        foundname = ctxkpse:find_file(name,"tex") or ""
+    end
+    if foundname == "" then
+        if not continue then
+            logs.report("system","unable to locate file '%s'",name)
+            os.exit()
+        end
+    else
+        if verbose then
+            logs.report("system","loading '%s'",foundname) -- no file.basename yet
+        end
+        dofile(foundname)
+    end
+end
+
+if non_generic_context.luatex_fonts.load_before then
+    loadmodule(non_generic_context.luatex_fonts.load_before,true)
+end
+
+if non_generic_context.luatex_fonts.skip_loading ~= true then
+
+    loadmodule('luatex-fonts-merged.lua',true)
+
+    if fonts then
+
+        if not fonts._merge_loaded_message_done_ then
+            texio.write_nl("log", "!")
+            texio.write_nl("log", "! I am using the merged version of 'luatex-fonts.lua' here. If")
+            texio.write_nl("log", "! you run into problems or experience unexpected behaviour, and")
+            texio.write_nl("log", "! if you have ConTeXt installed you can try to delete the file")
+            texio.write_nl("log", "! 'luatex-font-merged.lua' as I might then use the possibly")
+            texio.write_nl("log", "! updated libraries. The merged version is not supported as it")
+            texio.write_nl("log", "! is a frozen instance. Problems can be reported to the ConTeXt")
+            texio.write_nl("log", "! mailing list.")
+            texio.write_nl("log", "!")
+        end
+
+        fonts._merge_loaded_message_done_ = true
+
+    else
+
+        -- The following helpers are a bit overkill but I don't want to mess up
+        -- context code for the sake of general generality. Around version 1.0
+        -- there will be an official api defined.
+        --
+        -- So, I will strip these libraries and see what is really needed so that
+        -- we don't have this overhead in the generic modules. The next section
+        -- is only there for the packager, so stick to using luatex-fonts with
+        -- luatex-fonts-merged.lua and forget about the rest. The following list
+        -- might change without prior notice (for instance because we shuffled
+        -- code around).
+
+        loadmodule("l-lua.lua")
+        loadmodule("l-lpeg.lua")
+        loadmodule("l-function.lua")
+        loadmodule("l-string.lua")
+        loadmodule("l-table.lua")
+        loadmodule("l-io.lua")
+        loadmodule("l-file.lua")
+        loadmodule("l-boolean.lua")
+        loadmodule("l-math.lua")
+        loadmodule("l-unicode.lua")
+
+        -- A few slightly higher level support modules:
+
+        loadmodule("util-str.lua")
+        loadmodule("util-fil.lua")
+
+        -- The following modules contain code that is either not used at all
+        -- outside context or will fail when enabled due to lack of other
+        -- modules.
+
+        -- First we load a few helper modules. This is about the miminum needed
+        -- to let the font modules do their work. Don't depend on their functions
+        -- as we might strip them in future versions of this generic variant.
+
+        loadmodule('luatex-basics-gen.lua')
+        loadmodule('data-con.lua')
+
+        -- We do need some basic node support. The code in there is not for
+        -- general use as it might change.
+
+        loadmodule('luatex-basics-nod.lua')
+
+        -- We ship a resources needed for font handling (more might end up here).
+
+        loadmodule('luatex-basics-chr.lua')
+
+        -- Now come the font modules that deal with traditional tex fonts as well
+        -- as open type fonts.
+        --
+        -- The font database file (if used at all) must be put someplace visible
+        -- for kpse and is not shared with context. The mtx-fonts script can be
+        -- used to generate this file (using the --reload --force --simple option).
+
+        loadmodule('font-ini.lua')
+        loadmodule('luatex-fonts-mis.lua')
+        loadmodule('font-con.lua')
+        loadmodule('luatex-fonts-enc.lua')
+        loadmodule('font-cid.lua')
+        loadmodule('font-map.lua')
+
+        -- We use a bit simpler database because using the context one demands
+        -- loading more helper code and although it is more flexible (more ways
+        -- to resolve and so) it will never be uses in plain/latex anyway, so
+        -- let's stick to a simple approach.
+
+        loadmodule('luatex-fonts-syn.lua')
+
+        -- We need some helpers.
+
+        loadmodule('font-vfc.lua')
+
+        -- This is the bulk of opentype code.
+
+        loadmodule('font-otr.lua')
+        loadmodule('font-oti.lua')
+        loadmodule('font-ott.lua')
+        loadmodule('font-cff.lua')
+        loadmodule('font-ttf.lua')
+        loadmodule('font-dsp.lua')
+        loadmodule('font-oup.lua')
+        loadmodule('font-otl.lua')
+        loadmodule('font-oto.lua')
+        loadmodule('font-otj.lua')
+        loadmodule('font-ota.lua')
+        loadmodule('font-ots.lua')
+        loadmodule('font-osd.lua')
+        loadmodule('font-ocl.lua')
+        loadmodule('font-otc.lua')
+
+        -- The code for type one fonts.
+
+        loadmodule('font-onr.lua')
+        loadmodule('font-one.lua')
+        loadmodule('font-afk.lua')
+
+        -- And for traditional TeX fonts.
+
+        loadmodule('font-tfm.lua')
+
+        -- Some common code.
+
+        loadmodule('font-lua.lua')
+        loadmodule('font-def.lua')
+
+        -- We support xetex compatible specifiers (plain/latex only).
+
+        loadmodule('luatex-fonts-def.lua') -- was font-xtx.lua
+
+        -- Here come some additional features.
+
+        loadmodule('luatex-fonts-ext.lua')
+        loadmodule('font-imp-tex.lua')
+        loadmodule('font-imp-ligatures.lua')
+        loadmodule('font-imp-italics.lua')
+        loadmodule('font-imp-effects.lua')
+        loadmodule('luatex-fonts-lig.lua')
+
+        -- We need to plug into a callback and the following module implements the
+        -- handlers. Actual plugging in happens later.
+
+        loadmodule('luatex-fonts-gbn.lua')
+
+    end
+
+end
+
+if non_generic_context.luatex_fonts.load_after then
+    loadmodule(non_generic_context.luatex_fonts.load_after,true)
+end
+
+resolvers.loadmodule = loadmodule
+
+-- In order to deal with the fonts we need to initialize some callbacks. One can overload them later
+-- on if needed. First a bit of abstraction.
+
+generic_context.callback_ligaturing           = false
+generic_context.callback_kerning              = false
+generic_context.callback_pre_linebreak_filter = nodes.simple_font_handler
+generic_context.callback_hpack_filter         = nodes.simple_font_handler
+generic_context.callback_define_font          = fonts.definers.read
+
+-- The next ones can be done at a different moment if needed. You can create a generic_context namespace
+-- and set no_callbacks_yet to true, load this module, and enable the callbacks later. So, there is really
+-- *no* need to create a alternative for luatex-fonts.lua and luatex-fonts-merged.lua: just load this one
+-- and overload if needed.
+
+if not generic_context.no_callbacks_yet then
+
+    callback.register('ligaturing',           generic_context.callback_ligaturing)
+    callback.register('kerning',              generic_context.callback_kerning)
+    callback.register('pre_linebreak_filter', generic_context.callback_pre_linebreak_filter)
+    callback.register('hpack_filter',         generic_context.callback_hpack_filter)
+    callback.register('define_font' ,         generic_context.callback_define_font)
+
+end
+
+-- We're done.
+
+logs.report("system","luatex-fonts.lua loaded in %0.3f seconds", os.gettimeofday()-starttime)
+
+generic_context.pop_namespaces(whatever)


Property changes on: trunk/Master/texmf-dist/source/luatex/luaotfload/fontloader-reference-load-order.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/luatex/luaotfload/fontloader-reference-load-order.tex
===================================================================
--- trunk/Master/texmf-dist/source/luatex/luaotfload/fontloader-reference-load-order.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/source/luatex/luaotfload/fontloader-reference-load-order.tex	2018-09-26 20:50:34 UTC (rev 48771)
@@ -0,0 +1,140 @@
+%D \module
+%D   [       file=luatex-fonts,
+%D        version=2009.12.01,
+%D          title=\LUATEX\ Support Macros,
+%D       subtitle=Generic \OPENTYPE\ Font Handler,
+%D         author=Hans Hagen,
+%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+
+%D \subject{Welcome}
+%D
+%D This file is one of a set of basic functionality enhancements
+%D for \LUATEX\ derived from the \CONTEXT\ \MKIV\ code base. Please
+%D don't polute the \type {luatex-*} namespace with code not coming
+%D from the \CONTEXT\ development team as we may add more files.
+%D
+%D As this is an experimental setup, it might not always work out as
+%D expected. Around \LUATEX\ version 0.50 we expect the code to be
+%D more or less okay.
+%D
+%D This file implements a basic font system for a bare \LUATEX\
+%D system. By default \LUATEX\ only knows about the classic \TFM\
+%D fonts but it can read other font formats and pass them to \LUA.
+%D With some glue code one can then construct a suitable \TFM\
+%D representation that \LUATEX\ can work with. For more advanced font
+%D support a bit more code is needed that needs to be hooked
+%D into the callback mechanism.
+%D
+%D This file is currently rather simple: it just loads the \LUA\ file
+%D with the same name. An example of a \type {luatex.tex} file that is
+%D just plain \TEX:
+%D
+%D \starttyping
+%D \catcode`\{=1 % left brace is begin-group character
+%D \catcode`\}=2 % right brace is end-group character
+%D
+%D \input plain
+%D
+%D \everyjob\expandafter{\the\everyjob\input luatex-fonts\relax}
+%D
+%D \dump
+%D \stoptyping
+%D
+%D We could load the \LUA\ file in \type {\everyjob} but maybe some
+%D day we need more here.
+%D
+%D When defining a font you can use two prefixes. A \type {file:}
+%D prefix forced a file search, while a \type {name:} prefix will
+%D result in consulting the names database. Such a database can be
+%D generated with:
+%D
+%D \starttyping
+%D mtxrun --usekpse --script fonts --names
+%D \stoptyping
+%D
+%D This will generate a file \type {luatex-fonts-names.lua} that has
+%D to be placed in a location where it can be found by \KPSE. Beware:
+%D the \type {--kpseonly} flag is only used outside \CONTEXT\ and
+%D provides very limited functionality, just enough for this task.
+%D
+%D The code loaded here does not come out of thin air, but is mostly
+%D shared with \CONTEXT, however, in that macropackage we go beyond
+%D what is provided here. When you use the code packaged here you
+%D need to keep a few things in mind:
+%D
+%D \startitemize
+%D
+%D \item This subsystem will be extended, improved etc. in about the
+%D same pace as \CONTEXT\ \MKIV. However, because \CONTEXT\ provides a
+%D rather high level of integration not all features will be supported
+%D in the same quality. Use \CONTEXT\ if you want more goodies.
+%D
+%D \item There is no official \API\ yet, which means that using
+%D functions implemented here is at your own risk, in the sense that
+%D names and namespaces might change. There will be a minimal \API\
+%D defined once \LUATEX\ version 1.0 is out. Instead of patching the
+%D files it's better to overload functions if needed.
+%D
+%D \item The modules are not stripped too much, which makes it
+%D possible to benefit from improvements in the code that take place
+%D in the perspective of \CONTEXT\ development. They might be split a
+%D bit more in due time so the baseline might become smaller.
+%D
+%D \item The code is maintained and tested by the \CONTEXT\
+%D development team. As such it might be better suited for this macro
+%D package and integration in other systems might demand some
+%D additional wrapping. Problems can be reported to the team but as we
+%D use \CONTEXT\ \MKIV\ as baseline, you'd better check if the problem
+%D is a general \CONTEXT\ problem too.
+%D
+%D \item The more high level support for features that is provided in
+%D \CONTEXT\ is not part of the code loaded here as it makes no sense
+%D elsewhere. Some experimental features are not part of this code
+%D either but some might show up later.
+%D
+%D \item Math font support will be added but only in its basic form
+%D once that the Latin Modern and \TEX\ Gyre math fonts are
+%D available.
+%D
+%D \item At this moment the more nifty speed-ups are not enabled
+%D because they work in tandem with the alternative file handling
+%D that \CONTEXT\ uses. Maybe around \LUATEX\ 1.0 we will bring some
+%D speedup into this code too (if it pays off at all).
+%D
+%D \item The code defines a few global tables. If this code is used
+%D in a larger perspective then you can best make sure that no
+%D conflicts occur. The \CONTEXT\ package expects users to work in
+%D their own namespace (\type {userdata}, \type {thirddata}, \type
+%D {moduledata} or \type {document}. The team takes all freedom to
+%D use any table at the global level but will not use tables that are
+%D named after macro packages. Later the \CONTEXT\ might operate in
+%D a more controlled namespace but it has a low priority.
+%D
+%D \item There is some tracing code present but this is not enabled
+%D and not supported outside \CONTEXT\ either as it integrates quite
+%D tightly into \CONTEXT. In case of problems you can use \CONTEXT\
+%D for tracking down problems.
+%D
+%D \item Patching the code in distributions is dangerous as it might
+%D fix your problem but introduce new ones for \CONTEXT. So, best keep
+%D the original code as it is.
+%D
+%D \item Attributes are (automatically) taken from the range 127-255 so
+%D you'd best not use these yourself.
+%D
+%D \stopitemize
+%D
+%D If this all sounds a bit tricky, keep in mind that it makes no sense
+%D for us to maintain multiple code bases and we happen to use \CONTEXT.
+%D
+%D For more details about how the font subsystem works we refer to
+%D publications in \TEX\ related journals, the \CONTEXT\ documentation,
+%D and the \CONTEXT\ wiki.
+
+\directlua {
+    if not fonts then
+        dofile(kpse.find_file("luatex-fonts.lua","tex"))
+    end
+}
+
+\endinput


Property changes on: trunk/Master/texmf-dist/source/luatex/luaotfload/fontloader-reference-load-order.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Deleted: trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload-latex.tex
===================================================================
--- trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload-latex.tex	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload-latex.tex	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,486 +0,0 @@
-\suppresslongerror1%% sigh ...
-%% Copyright (C) 2009-2015
-%%
-%%      by  Elie Roux      <elie.roux at telecom-bretagne.eu>
-%%      and Khaled Hosny   <khaledhosny at eglug.org>
-%%      and Philipp Gesang <phg at phi-gamma.net>
-%%
-%% This file is part of Luaotfload.
-%%
-%%      Home:      https://github.com/lualatex/luaotfload
-%%      Support:   <lualatex-dev at tug.org>.
-%%
-%% Luaotfload is under the GPL v2.0 (exactly) license.
-%%
-%% ----------------------------------------------------------------------------
-%%
-%% Luaotfload is free software; you can redistribute it and/or
-%% modify it under the terms of the GNU General Public License
-%% as published by the Free Software Foundation; version 2
-%% of the License.
-%%
-%% Luaotfload is distributed in the hope that it will be useful,
-%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-%% GNU General Public License for more details.
-%%
-%% You should have received a copy of the GNU General Public License
-%% along with Luaotfload; if not, see <http://www.gnu.org/licenses/>.
-%%
-%% ----------------------------------------------------------------------------
-%%
-
-\documentclass{ltxdoc}
-
-\makeatletter
-
-\usepackage {metalogo,multicol,fancyvrb,xspace}
-\usepackage [x11names] {xcolor}
-
-\def \primarycolor   {DodgerBlue4} %%-> rgb  16  78 139 | #104e8b
-\def \secondarycolor {Goldenrod4}  %%-> rgb 139 105 200 | #8b6914
-
-\usepackage[
-    bookmarks=true,
-   colorlinks=true,
-    linkcolor=\primarycolor,
-     urlcolor=\secondarycolor,
-    citecolor=\primarycolor,
-     pdftitle={The Luaotfload package},
-   pdfsubject={OpenType layout system for Plain TeX and LaTeX},
-    pdfauthor={Elie Roux & Khaled Hosny & Philipp Gesang},
-  pdfkeywords={luatex, lualatex, unicode, opentype}
-]{hyperref}
-
-\usepackage {fontspec}
-\usepackage {unicode-math}
-
-\setmainfont[
-% Numbers     = OldStyle, %% buggy with font cache
-  Ligatures   = TeX,
-  BoldFont    = {Linux Libertine O Bold},
-  ItalicFont  = {Linux Libertine O Italic},
-  SlantedFont = {Linux Libertine O Italic},
-]{Linux Libertine O}
-\setmonofont[Ligatures=TeX,Scale=MatchLowercase]{Liberation Mono}
-%setsansfont[Ligatures=TeX]{Linux Biolinum O}
-\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{Iwona Medium}
-%setmathfont{XITS Math}
-
-\usepackage{hologo}
-
-\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\LUALATEX {Lua\LaTeX\xspace}
-\newcommand\CONTEXT  {Con\TeX t\xspace}
-\newcommand\OpenType {\identifier{Open\kern-.25ex Type}\xspace}
-
-%% \groupedcommand, with some omissions taken from syst-aux.mkiv
-\let \handlegroupnormalbefore \relax
-\let \handlegroupnormalafter  \relax
-
-\protected \def \handlegroupnormal #1#2{%
-  \bgroup % 1
-  \def \handlegroupbefore {#1}%
-  \def \handlegroupafter  {#2}%
-  \afterassignment \handlegroupnormalbefore
-  \let \next =
-}
-
-\def \handlegroupnormalbefore {%
-  \bgroup % 2
-  \handlegroupbefore
-  \bgroup % 3
-  \aftergroup \handlegroupnormalafter%
-}
-
-\def \handlegroupnormalafter {%
-  \handlegroupafter
-  \egroup % 3
-  \egroup % 2
-}
-
-\let \groupedcommand \handlegroupnormal %% only the two arg version
-
-\def \definehighlight [#1][#2]{%
-  \ifcsname #1\endcsname\else
-    \expandafter\def\csname #1\endcsname{%
-      \leavevmode
-      \groupedcommand {#2}\empty%
-    }
-  \fi%
-}
-
-%% old, simplistic definition: obsolete now that we have
-%% \groupedcommand
-%\def\definehighlight[#1][#2]%
- %{\ifcsname #1\endcsname\else
-    %\expandafter\def\csname #1\endcsname%
-      %{\bgroup#2\csname #1_indeed\endcsname}
-    %\expandafter\def\csname #1_indeed\endcsname##1%
-      %{##1\egroup}%
-  %\fi}
-
-\def\restoreunderscore{\catcode`\_=12\relax}
-
-\definehighlight         [fileent][\ttfamily\restoreunderscore]         %% files, dirs
-\definehighlight        [texmacro][\sffamily\itshape\textbackslash]     %% cs
-\definehighlight        [luaident][\sffamily\itshape\restoreunderscore] %% lua identifiers
-\definehighlight      [identifier][\sffamily]                           %% names
-\definehighlight          [abbrev][\rmfamily\scshape]                   %% acronyms
-\definehighlight        [emphasis][\rmfamily\slshape]                   %% level 1 emph
-
-\definehighlight       [Largefont][\Large]                              %% font size
-\definehighlight       [smallcaps][\sc]                                 %% font feature
-\definehighlight [nonproportional][\tt]                                 %% font switch
-
-\newcommand*\email[1]{\href{mailto:#1}{#1}}
-
-\renewcommand\partname{Part}%% gets rid of the stupid “file” heading
-
-\usepackage{syntax}%% bnf for font request syntax
-
-\usepackage{titlesec}
-
-\def\movecountertomargin#1{\llap{\rmfamily\upshape#1\hskip2em}}
-\def\zeropoint{0pt}
-\titleformat \part
-             {\normalsize\rmfamily\bfseries}
-             {\movecountertomargin\thepart} \zeropoint {}
-\titleformat \section
-             {\normalsize\rmfamily\scshape}
-             {\movecountertomargin\thesection} \zeropoint {}
-\titleformat \subsection
-             {\small\rmfamily\itshape}
-             {\movecountertomargin\thesubsection} \zeropoint {}
-\titleformat \subsubsection
-             {\normalsize\rmfamily\upshape}
-             {\movecountertomargin\thesubsubsection} \zeropoint {}
-
-\usepackage{tocloft}
-\renewcommand \cftpartfont   {\rmfamily\upshape}
-\renewcommand \cftsecfont    {\rmfamily\upshape}
-\renewcommand \cftsubsecfont {\rmfamily\upshape}
-\setlength \cftbeforepartskip {1ex}
-\setlength \cftbeforesecskip  {1ex}
-
-\VerbatimFootnotes
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% structurals
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\def \definestructural #1{%
-  \expandafter \let \csname end#1\endcsname \relax
-
-  \expandafter \def \csname begin#1\endcsname {%
-    \@ifnextchar[{\csname begin#1indeed\endcsname}
-                 {\csname begin#1indeed\endcsname[]}%
-  }
-
-  \expandafter \def \csname begin#1indeed\endcsname [##1]##2{%
-    \edef \first {##1}%
-    \ifx \first \empty
-      \csname #1\endcsname [##2]{##2}%
-    \else
-      \csname #1\endcsname [\first]{##2}%
-    \fi
-  }
-}
-
-\definestructural {section}
-\definestructural {subsection}
-\definestructural {subsubsection}
-
-\def \fakesection #1{\section*{#1}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% inline verbatim
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% Context offers both \type{…} and \type<<…>>, but not an unbalanced
-%% one that we could map directly onto Latex’s \verb|…|.
-
-\usepackage {listings}
-\usepackage {luatexbase}
-\lstset {
-  basicstyle=\ttfamily,
-}
-
-%\let \inlinecode \lstinline
-\protected \def \inlinecode {\lstinline}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% codelistings; this sucks hard since we lack access to buffers
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\newcount \othercatcode  \othercatcode 12
-\newcount \activecatcode \othercatcode 13
-
-\newcatcodetable \vrbcatcodes
-\setcatcodetable \vrbcatcodes {%
-  \catcodetable \CatcodeTableIniTeX
-  \catcode  9 \othercatcode %% \tabasciicode
-  \catcode 13 \othercatcode %% \endoflineasciicode
-  \catcode 12 \othercatcode %% \formfeedasciicode
-  \catcode 26 \othercatcode %% \endoffileasciicode
-  \catcode 32 \othercatcode %% \spaceasciicode
-}
-
-\directlua {
-  document = document or { }
-  document.vrbcatcodesidx = tonumber (\the \vrbcatcodes)
-}
-
-\newcatcodetable \literalcatcodes
-\setcatcodetable \literalcatcodes {%
-  \catcodetable \CatcodeTableString
-  \catcode 32 \activecatcode %% \spaceasciicode
-}
-
-\def \listingsurroundskip {\vskip \baselineskip}
-
-\def \beginlisting {%
-  \noindent
-  \begingroup
-    \catcodetable \vrbcatcodes
-    \beginlistingindeed%
-}
-
-\directlua {
-  local texsprint       = tex.sprint
-  local stringis_empty  = string.is_empty
-  local stringsub       = string.sub
-  local stringgsub      = string.gsub
-  %local backslash       = unicode.utf8.char (0x200c)
-  local backslash       = unicode.utf8.char (0x5c)
-  local escaped         = [[\string\string\string\]]
-  document.printlines = function (buffer)
-    local lines = string.explode (buffer, "\noexpand\n")
-    print ""
-    for i, line in next, lines do
-      local line = stringgsub (line, backslash, escaped)
-      if stringis_empty (line) then
-        print (i, "listing: <empty line />")
-        texsprint [[\string\listingpar]]
-      else
-        local line = [[\string\beginlistingline]]
-                  .. line
-                  .. [[\string\endlistingline]]
-                  .. [[\string\listingpar]]
-        print (i, "listing: «" .. line .. "»")
-        texsprint (document.vrbcatcodesidx, line)
-      end
-    end
-  end
-}
-
-\def \listingpar {\endgraf}
-
-\let \endlistingline \relax
-\let \endlisting     \relax
-
-\protected \def \beginlistingline{%
-  \leavevmode
-  \begingroup
-    \beginlistinglineindeed%
-}
-
-\def \beginlistinglineindeed #1\endlistingline{%
-  \endgroup
-  \hbox{%
-    \addfontfeature {RawFeature=-tlig;-liga}%% So one can’t just turn them all off at once using the ``Ligatures`` key?
-    \obeyspaces
-    #1}%
-}
-
-\def \beginlistingindeed#1\endlisting{%
-  \endgroup
-  \begingroup
-    \endgraf
-    \listingsurroundskip
-    \ttfamily
-    \small
-    \parindent = 0em
-    \leftskip = 2em
-    \hangindent = 2em
-    \directlua{document.printlines ([==[\detokenize {#1}]==])}%
-    \listingsurroundskip
-  \endgroup
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% enumerations and lists
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\def \definelist [#1]#2{% name, itemcode
-  \expandafter \def \csname begin#1\endcsname {%
-    \begin {itemize}
-      \let \normalitem = \item
-      \def \altitem ####1{%
-        \def \first {####1}%
-        #2
-      }
-      \let \beginnormalitem \item
-      \let \endnormalitem   \relax
-      \let \beginaltitem    \altitem
-      \let \endaltitem      \relax
-  }
-
-  \expandafter \def \csname end#1\endcsname {%
-    \end {itemize}
-  }
-}
-
-\definelist  [descriptions]{\normalitem {\textbf \first}\hfill\break}
-\definelist   [definitions]{\normalitem {\fileent {\first}}}
-\definelist      [filelist]{\normalitem {\fileent {\first}}\space--\hskip 1em}
-\definelist  [functionlist]{\normalitem {\luaident {\first}}\hfill\break}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% columns
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\def \begindoublecolumns {\begin {multicols} {2}}
-\def \enddoublecolumns   {\end {multicols}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% alignment
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\def \begincentered {\begin {center}}
-\def \endcentered   {\end {center}}
-
-\def \beginnarrower {\begin {quote}}
-\def \endnarrower   {\end {quote}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% special elements
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\let \beginfrontmatter \relax
-\let \endfrontmatter   \relax
-
-\def \beginabstractcontent {\begin {abstract}}
-\def \endabstractcontent   {\end {abstract}}
-
-\let \setdocumenttitle      \title
-\let \setdocumentdate       \date
-\let \setdocumentauthor     \author
-\let \typesetdocumenttitle  \maketitle
-
-\AtBeginDocument {%% seriously?
-  \let \typesetcontent \tableofcontents%
-}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% floats
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% syntax definition
-\def \beginsyntaxfloat #1#2{%% #1:label #2:caption
-  \begin {figure} [b]
-    \edef \syntaxlabel  {#1}%
-    \def \syntaxcaption {#2}%
-    \setlength\grammarparsep{12pt plus 2pt minus 2pt}%
-    \setlength\grammarindent{5cm}%
-    \begingroup
-      \small
-      \begin {grammar}
-}
-
-\def \endsyntaxfloat {%
-      \end {grammar}
-    \endgroup
-    \caption \syntaxcaption
-    \label   \syntaxlabel
-  \end {figure}
-}
-
-%% figures, e.g. the file graph
-\def \figurefloat #1#2#3{%% #1:label #2:caption #3:file
-  \begin {figure} [b]
-    \caption {#2}%
-    \includegraphics[width=\textwidth]{#3}%
-    \label {#1}
-  \end {figure}
-}
-
-%% tables
-\def \tablefloat #1#2{%% #1:label #2:caption
-  \begin {table} [t]
-    \hrule
-    \caption {#2}%
-    \label {#1}
-    \hrule
-  \end {table}
-}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% hyperlinks
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\protected \def \hyperlink{%
-  \@ifnextchar[{\hyperlinkindeed}%
-               {\hyperlinkindeed[]}%
-}
-
-\def \hyperlinkindeed [#1]#2{%
-  \def \first {#1}%
-  \ifx \first \empty
-    \url {#2}%
-  \else
-    \href {#2}{#1}%
-  \fi%
-}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% tables
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Our tables aren’t anything special so we stick with “tabular” on the
-%% Latex end.
-%%
-%% This is going to be largely incompatible with Context since format
-%% specifications work quite differently (even between different
-%% Context table variants).
-
-\def \begintabulate [#1]#2\endtabulate{%
-  \begingroup
-    \let \beginrow  = \relax %% -> \NC in Context
-    \let \newcell   = &      %% -> \NC
-    \let \endrow    = \cr    %% -> \NC \NR
-    \begin {tabular}{#1}%
-      #2
-    \end {tabular}
-  \endgroup
-}
-
-\let \endtabulate \relax
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% escaped characters
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\let \charpercent   \textpercent
-\let \charbackslash \textbackslash
-\let \chartilde     \textasciitilde
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% main
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\makeatother
-
-\newif \ifcontextmkiv \contextmkivfalse
-
-\begin {document}
-  \input {luaotfload-main.tex}
-\end {document}
-
-

Deleted: trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex
===================================================================
--- trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,1908 +0,0 @@
-%% Copyright (C) 2009-2017
-%%
-%%      by  Elie Roux      <elie.roux at telecom-bretagne.eu>
-%%      and Khaled Hosny   <khaledhosny at eglug.org>
-%%      and Philipp Gesang <phg at phi-gamma.net>
-%%
-%% This file is part of Luaotfload.
-%%
-%%      Home:      https://github.com/lualatex/luaotfload
-%%      Support:   <lualatex-dev at tug.org>.
-%%
-%% Luaotfload is under the GPL v2.0 (exactly) license.
-%%
-%% ----------------------------------------------------------------------------
-%%
-%% Luaotfload is free software; you can redistribute it and/or
-%% modify it under the terms of the GNU General Public License
-%% as published by the Free Software Foundation; version 2
-%% of the License.
-%%
-%% Luaotfload is distributed in the hope that it will be useful,
-%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-%% GNU General Public License for more details.
-%%
-%% You should have received a copy of the GNU General Public License
-%% along with Luaotfload; if not, see <http://www.gnu.org/licenses/>.
-%%
-%% ----------------------------------------------------------------------------
-%%
-
-\beginfrontmatter
-
-  \setdocumenttitle  {The \identifier{luaotfload} package}
-  \setdocumentdate   {2017/01/29 v2.8}
-  \setdocumentauthor {Elie Roux · Khaled Hosny · Philipp Gesang\\
-                      Home:    \hyperlink {https://github.com/lualatex/luaotfload}\\
-                      Support: \email     {lualatex-dev at tug.org}}
-
-  \typesetdocumenttitle
-
-  \beginabstractcontent
-    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.
-
-    After discussion of the font loading API, this manual gives an
-    overview of the core components of \identifier{Luaotfload}: The
-    packaged font loader code, the names database, configuration, and
-    helper functions on the \LUA\ end.
-  \endabstractcontent
-
-\endfrontmatter
-
-\typesetcontent
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\beginsection {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 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 \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{%
-  Unfortunately, \identifier{luaotfload} doesn‘t support many Indic
-  scripts right now.
-  Assistance in implementing the prerequisites is greatly
-  appreciated.
-}
-scripts.
-
-\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.
-
-However, until recently the only way to use them directly in the \TEX
-world was with the \XETEX engine.
-
-Unlike \XETEX, \LUATEX has no built-in support for \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.
-
-\endsection
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\beginsection {Thanks}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\identifier{Luaotfload} is part of \LUALATEX, the community-driven
-project to provide a foundation for using the \LATEX format with the
-full capabilites of the \LUATEX engine.
-%
-As such, the distinction between end users, contributors, and project
-maintainers is intentionally kept less strict, lest we unduly
-personalize the common effort.
-
-Nevertheless, the current maintainers would like to express their
-gratitude to Khaled Hosny, Akira Kakuto, Hironori Kitagawa and Dohyun
-Kim.
-%
-Their contributions -- be it patches, advice, or systematic
-testing -- made the switch from version 1.x to 2.2 possible.
-%
-Also, Hans Hagen, the author of the font loader, made porting the
-code to \LATEX a breeze due to the extra effort he invested into
-isolating it from the rest of \CONTEXT, not to mention his assistance
-in the task and willingness to respond to our suggestions.
-
-\endsection
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\beginsection {Loading Fonts}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\identifier{luaotfload} supports an extended font request syntax:
-
-\beginnarrower
-      \nonproportional{\string\font\string\foo\space= \string{}%
-      \meta{prefix}\nonproportional{:}%
-      \meta{font name}\nonproportional{:}%
-      \meta{font features}\nonproportional{\string}}%
-      \meta{\TEX font features}
-\endnarrower
-
-\noindent
-The curly brackets are optional and escape the spaces in the enclosed
-font name.
-%
-Alternatively, double quotes serve the same purpose.
-%
-A selection of individual parts of the syntax are discussed below;
-for a more formal description see figure \ref{font-syntax}.
-
-\beginsyntaxfloat
-  {font-syntax}
-  {Font request syntax.
-   Braces or double quotes around the
-   \emphasis{specification} rule will
-   preserve whitespace in file names.
-   In addition to the font style modifiers
-   (\emphasis{slash-notation}) given above, there
-   are others that are recognized but will be silently
-   ignored: \nonproportional{aat},
-            \nonproportional{icu}, and
-            \nonproportional{gr}.
-   The special terminals are:
-   \smallcaps {feature\textunderscore id} for a valid font
-      feature name and
-   \smallcaps {feature\textunderscore value} for the corresponding
-      value.
-   \smallcaps {tfmname} is the name of a \abbrev{tfm} file.
-   \smallcaps {digit}  again refers to bytes 48--57, and
-   \smallcaps {all\textunderscore characters} to all byte values.
-   \smallcaps {csname} and \smallcaps {dimension} are the \TEX concepts.}
-%
-      <definition>      ::= `\\font', {\sc csname}, `=', <font request>, [ <size> ] ;
-
-      <size>            ::= `at', {\sc dimension} ;
-
-      <font request>    ::= `"', <unquoted font request> `"'
-      \alt                  `{', <unquoted font request> `}'
-      \alt                  <unquoted font request> ;
-
-      <unquoted font request> ::= <specification>, [`:', <feature list> ]
-      \alt                        <path lookup>, [ [`:'], <feature list> ] ;
-
-      <specification>    ::= <prefixed spec>, [ <subfont no> ], \{ <modifier> \}
-      \alt                   <anon lookup>, \{ <modifier> \} ;
-
-      <prefixed spec>    ::= `combo:', <combo list>
-      \alt                   `file:', <file lookup>
-      \alt                   `name:', <name lookup> ;
-
-      <combo list>       ::= <combo def 1>, \{ `;', <combo def>  \} ;
-
-      <combo def 1>      ::= <combo id>, `->', <combo id> ;
-
-      <combo def>        ::= <combo id>, `->', <combo id chars> ;
-
-      <combo id>         ::= (`(', \{ {\sc digit} \}, `)' | \{ {\sc digit} \} ) ;
-
-      <combo id chars>   ::= (`(', \{ {\sc digit} \}, `,', <combo chars>, `)'
-      \alt                   \{ {\sc digit} \} ) ;
-
-      <combo chars>      ::= `fallback'
-      \alt                   \{ <combo range>, \{ `*', <combo range> \} \} ;
-
-      <combo range>      ::= <combo num>, [ `-', <combo num> ] ;
-
-      <combo num>        ::= `0x', \{ {\sc hexdigit}  \}
-      \alt                   `U+', \{ {\sc digit} \}
-      \alt                   \{ {\sc digit} \} ;
-
-      <file lookup>      ::= \{ <name character> \} ;
-
-      <name lookup>      ::= \{ <name character> \} ;
-
-      <anon lookup>      ::= {\sc tfmname} | <name lookup> ;
-
-      <path lookup>      ::= `[', \{ <path content> \}, `]', [ <subfont no> ] ;
-
-      <path content>     ::= <path balanced>
-      \alt                   `\\', {\sc all_characters}
-      \alt                   {\sc all_characters} - `]'
-
-      <path balanced>    ::= `[', [ <path content> ], `]'
-
-      <modifier>         ::= `/', (`I' | `B' | `BI' | `IB' | `S=', \{ {\sc digit} \} ) ;
-
-      <subfont no>       ::= `(', \{ {\sc digit} \}, `)' ;
-
-      <feature list>     ::= <feature expr>, \{ `;', <feature expr> \} ;
-
-      <feature expr>     ::= {\sc feature_id}, `=', {\sc feature_value}
-      \alt                   <feature switch>, {\sc feature_id} ;
-
-      <feature switch>   ::= `+' | `-' ;
-
-      <name character>   ::= {\sc all_characters} - ( `(' | `/' | `:' ) ;
-\endsyntaxfloat
-
-%% Below guarded space gets borked in index; why‽
-\beginsubsection{Prefix -- the \identifier{luaotfload}{ }Way}
-
-In \identifier{luaotfload}, the canonical syntax for font requests
-requires a \emphasis{prefix}:
-%
-\beginnarrower
-  \nonproportional{\string\font\string\fontname\space= }%
-  \meta{prefix}%
-  \nonproportional{:}%
-  \meta{fontname}%
-  \dots
-\endnarrower
-%
-where \meta{prefix} is either \inlinecode{file:} or \inlinecode {name:}.\footnote{%
-  \identifier{Luaotfload} also knows two further prefixes, \inlinecode {kpse:}
-  and \inlinecode {my:}.
-  %
-  A \inlinecode {kpse} lookup is restricted to files that can be found by
-  \identifier{kpathsea} and will not attempt to locate system fonts.
-  %
-  This behavior can be of value when an extra degree of encapsulation is
-  needed, for instance when supplying a customized tex distribution.
-
-  The \inlinecode {my} lookup takes this a step further: it lets you define
-  a custom resolver function and hook it into the \luaident{resolve_font}
-  callback.
-  %
-  This ensures full control over how a file is located.
-  %
-  For a working example see the
-  \hyperlink [test repo]{https://bitbucket.org/phg/lua-la-tex-tests/src/5f6a535d/pln-lookup-callback-1.tex}.
-}
-%
-It determines whether the font loader should interpret the request as
-a \emphasis{file name} or
-  \emphasis{font name}, respectively,
-which again influences how it will attempt to locate the font.
-%
-Examples for font names are
-            “Latin Modern Italic”,
-            “GFS Bodoni Rg”, and
-            “PT Serif Caption”
--- they are the human readable identifiers
-usually listed in drop-down menus and the like.\footnote{%
-  Font names may appear like a great choice at first because they
-  offer seemingly more intuitive identifiers in comparison to arguably
-  cryptic file names:
-  %
-  “PT Sans Bold” is a lot more descriptive than \fileent{PTS75F.ttf}.
-  On the other hand, font names are quite arbitrary and there is no
-  universal method to determine their meaning.
-  %
-  While \identifier{luaotfload} provides fairly sophisticated heuristic
-  to figure out a matching font style, weight, and optical size, it
-  cannot be relied upon to work satisfactorily for all font files.
-  %
-  For an in-depth analysis of the situation and how broken font names
-  are, please refer to
-  \hyperlink [this post]{http://www.ntg.nl/pipermail/ntg-context/2013/073889.html}
-  by Hans Hagen, the author of the font loader.
-  %
-  If in doubt, use filenames.
-  %
-  \fileent{luaotfload-tool} can perform the matching for you with the
-  option \inlinecode {--find=<name>}, and you can use the file name it returns
-  in your font definition.
-}
-%
-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.
-
-File names are whatever your file system allows them to be, except
-that that they may not contain the characters
-  \inlinecode {(},
-  \inlinecode {:}, and
-  \inlinecode {/}.
-%
-As is obvious from the last exception, the \inlinecode {file:} lookup will
-not process paths to the font location -- only those
-files found when generating the database are addressable this way.
-%
-Continue below in the \XETEX section if you need to load your fonts
-by path.
-%
-The file names corresponding to the example font names above are
-  \fileent{lmroman12-italic.otf},
-  \fileent{GFSBodoni.otf}, and
-  \fileent{PTZ56F.ttf}.
-
-\endsubsection
-
-\beginsubsection {Bracketed Lookups}
-\label{sec:conf}
-Bracketed lookups allow for arbitrary character content to be used in a
-definition.
-%
-A simple bracketed request looks follows the scheme
-
-\beginnarrower
-  \nonproportional{\string\font\string\fontname\space = [}%
-  \meta{/path/to/file}%
-  \nonproportional{]}
-\endnarrower
-
-\noindent
-Inside the square brackets, every character except for a closing bracket is
-permitted, allowing for  arbitrary paths to a font file -- including Windows
-style paths with UNC or drive letter prepended -- to be specified.
-%
-The \identifier{Luaotfload} syntax differs from \XETEX in that the subfont
-selector goes \emphasis{after} the closing bracket:
-
-\beginnarrower
-  \nonproportional{\string\font\string\fontname\space = [}%
-  \meta{/path/to/file}%
-  \nonproportional{]}
-  \nonproportional{(}n\nonproportional{)}
-\endnarrower
-
-Naturally, path-less file names are equally valid and processed the
-same way as an ordinary \inlinecode {file:} lookup.
-
-\beginsubsection {Compatibility}
-
-In addition to the regular prefixed requests, \identifier{luaotfload}
-accepts loading fonts the \XETEX way.
-%
-There are again two modes: bracketed and unbracketed.
-For the bracketed variety, see above, \ref{sec:conf}.
-
-Unbracketed (or, for lack of a better word: \emphasis{anonymous})
-font requests resemble the conventional \TEX syntax.
-
-\beginnarrower
-  \nonproportional{\string\font\string\fontname\space= }%
-  \meta{font name}
-  \dots
-\endnarrower
-\endsubsection
-
-However, they have a broader spectrum of possible interpretations:
-before anything else, \identifier{luaotfload} attempts to load a
-traditional \TEX Font Metric (\abbrev{tfm} or \abbrev{ofm}).
-%
-If this fails, it performs a \inlinecode {path:} lookup, which itself will
-fall back to a \inlinecode {file:} lookup.
-%
-Lastly, if none of the above succeeded, attempt to resolve the request as a
-\inlinecode {name:} lookup by searching the font index for \meta{font name}.
-%
-The behavior of this “anonymous” lookup is configurable, see the configuation
-manpage for details.
-
-Furthermore, \identifier{luaotfload} supports the slashed (shorthand)
-font style notation from \XETEX.
-
-\beginnarrower
-  \nonproportional{\string\font\string\fontname\space= }%
-  \meta{font name}%
-  \nonproportional{/}%
-  \meta{modifier}
-  \dots
-\endnarrower
-
-\noindent
-Currently, four style modifiers are supported:
-  \inlinecode {I} for italic shape,
-  \inlinecode {B} for bold   weight,
-  \inlinecode {BI} or \inlinecode {IB} for the combination of both.
-%
-Other “slashed” modifiers are too specific to the \XETEX engine and
-have no meaning in \LUATEX.
-
-\endsubsection
-
-\beginsubsection{Examples}
-
-\beginsubsubsection{Loading by File Name}
-
-For example, conventional \TeX\ font can be loaded with a
-\inlinecode {file:} request like so:
-
-\beginlisting
-  \font \lmromanten = {file:ec-lmr10} at 10pt
-\endlisting
-
-The \OpenType version of Janusz Nowacki’s font \emphasis{Antykwa
-Półtawskiego}\footnote{%
-  \hyperlink {http://jmn.pl/antykwa-poltawskiego/}, also available in
-  in \TEX Live.
-}
-in its condensed variant can be loaded as follows:
-
-\beginlisting
-  \font \apcregular = file:antpoltltcond-regular.otf at 42pt
-\endlisting
-
-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:
-
-\beginlisting
-  \font \gfsporson = "[/tmp/GFSPorson.otf]" at 12pt
-\endlisting
-
-\identifier{TrueType} collection files (the extension is usually
-\inlinecode{.ttc}) contain more than a single font. In order to refer to these
-subfonts, the respective index may be added in parentheses after the file
-name.\footnote{%
-  Incidentally, this syntactical detail also prevents one from loading files
-  that end in balanced parentheses.
-}
-
-\beginlisting
-  \font \cambriamain = "file:cambria.ttc(0)" at 10pt
-  \font \cambriamath = "file:cambria.ttc(1)" at 10pt
-\endlisting
-
-and likewise, requesting subfont inside a TTC container by path:
-
-\beginlisting
-  \font \asanamain = "[/home/typesetter/.fonts/math/asana.ttc](0):mode=node;+tlig" at 10pt
-  \font \asanamath = "[/home/typesetter/.fonts/math/asana.ttc](1):mode=base" at 10pt
-\endlisting
-
-\endsubsubsection
-
-\beginsubsubsection{Loading by Font Name}
-
-The \inlinecode {name:} lookup does not depend on cryptic filenames:
-
-\beginlisting
-  \font \pagellaregular = {name:TeX Gyre Pagella} at 9pt
-\endlisting
-
-A bit more specific but essentially the same lookup would be:
-
-\beginlisting
-  \font \pagellaregular = {name:TeX Gyre Pagella Regular} at 9pt
-\endlisting
-
-\noindent
-Which fits nicely with the whole set:
-
-\beginlisting
-  \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}
-
-  ...
-\endlisting
-
-\endsubsubsection
-
-\beginsubsubsection{Modifiers}
-
-If the entire \emphasis{Iwona} family\footnote{%
-  \hyperlink {http://jmn.pl/kurier-i-iwona/},
-  also in \TEX Live.
-}
-is installed in some location accessible by \identifier{luaotfload},
-the regular shape can be loaded as follows:
-
-\beginlisting
-  \font \iwona = Iwona at 20pt
-\endlisting
-
-\noindent
-To load the most common of the other styles, the slash notation can
-be employed as shorthand:
-
-\beginlisting
-  \font \iwonaitalic     = Iwona/I    at 20pt
-  \font \iwonabold       = Iwona/B    at 20pt
-  \font \iwonabolditalic = Iwona/BI   at 20pt
-\endlisting
-
-\noindent
-which is equivalent to these full names:
-
-\beginlisting
-  \font \iwonaitalic     = "Iwona Italic"       at 20pt
-  \font \iwonabold       = "Iwona Bold"         at 20pt
-  \font \iwonabolditalic = "Iwona BoldItalic"   at 20pt
-\endlisting
-
-\endsubsubsection
-\endsubsection
-\endsection
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\beginsection {Font features}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\emphasis{Font features} are the second to last component in the
-general scheme for font requests:
-
-\beginnarrower
-  \nonproportional{\string\font\string\foo\space= "}%
-  \meta{prefix}%
-  \nonproportional{:}%
-  \meta{font name}%
-  \nonproportional{:}%
-  \meta{font features}%
-  \meta{\TEX font features}%
-  \nonproportional{"}
-\endnarrower
-
-\noindent
-If style modifiers are present (\XETEX style), they must precede
-\meta{font features}.
-
-The element \meta{font features} is a semicolon-separated list of feature
-tags\footnote{%
-  Cf. \hyperlink {http://www.microsoft.com/typography/otspec/featurelist.htm}.
-}
-and font options.
-%
-Prepending a font feature with a \inlinecode{+} (plus sign) enables it,
-whereas a \inlinecode{-} (minus) disables it. For instance, the request
-
-\beginlisting
-  \font \test = LatinModernRoman:+clig;-kern
-\endlisting
-
-\noindent activates contextual ligatures (\inlinecode{clig}) and
-disables kerning (\inlinecode{kern}).
-%
-Alternatively the options \inlinecode{true} or \inlinecode{false} can
-be passed to the feature in a key/value expression.
-%
-The following request has the same meaning as the last one:
-
-\beginlisting
-  \font \test = LatinModernRoman:clig=true;kern=false
-\endlisting
-
-\noindent
-Furthermore, this second syntax is required should a font feature
-accept other options besides a true/false switch.
-%
-For example, \emphasis{stylistic alternates} (\inlinecode{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, \inlinecode{random}.
-
-%% TODO   verify that this actually works with a font that supports
-%%        the salt/random feature!\fi
-\beginlisting
-  \font \librmsaltfirst = LatinModernRoman:salt=1
-\endlisting
-
-\beginsubsection {Basic font features}
-
-\begindescriptions
-
-  \beginaltitem {mode}
-         \identifier{luaotfload} has two \OpenType processing
-         \emphasis{modes}:
-         \identifier{base} and \identifier{node}.
-
-         \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 \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.
-
-         By default \identifier{luaotfload} is in \identifier{node}
-         mode, and \identifier{base} mode has to be requested where needed,
-         e.~g. for math fonts.
-  \endaltitem
-
-  \beginaltitem {script} \label{script-tag}
-         An \OpenType script tag;\footnote{%
-           See \hyperlink {http://www.microsoft.com/typography/otspec/scripttags.htm}
-           for a list of valid values.
-           %
-           For scripts derived from the Latin alphabet the value
-           \inlinecode{latn} is good choice.
-         }
-         the default value is \inlinecode{dflt}.
-         %
-         Some fonts, including very popular ones by foundries like Adobe,
-         do not assign features to the \inlinecode{dflt} script, in
-         which case the script needs to be set explicitly.
-  \endaltitem
-
-  \beginaltitem {language}
-         An \OpenType language system identifier,\footnote{%
-           Cf. \hyperlink {http://www.microsoft.com/typography/otspec/languagetags.htm}.
-         }
-         defaulting to \inlinecode{dflt}.
-  \endaltitem
-
-  \beginaltitem {color}
-         A font color, defined as a triplet of two-digit hexadecimal
-         \abbrev{rgb} values, with an optional fourth value for
-         transparency
-         (where \inlinecode{00} is completely transparent and
-         \inlinecode{FF} is opaque).
-
-         For example, in order to set text in semitransparent red:
-
-         \beginlisting
-      \font \test = "Latin Modern Roman:color=FF0000BB"
-         \endlisting
-  \endaltitem
-
-  \beginaltitem {kernfactor \& letterspace}
-         Define a font with letterspacing (tracking) enabled.
-         %
-         In \identifier{luaotfload}, letterspacing is implemented by
-         inserting additional kerning between glyphs.
-
-         This approach is derived from and still quite similar to the
-         \emphasis{character kerning} (\texmacro{setcharacterkerning} /
-         \texmacro{definecharacterkerning} \& al.) functionality of
-         Context, see the file \fileent{typo-krn.lua} there.
-         %
-         The main difference is that \identifier{luaotfload} does not
-         use \LUATEX attributes to assign letterspacing to regions,
-         but defines virtual letterspaced versions of a font.
-
-         The option \identifier{kernfactor} accepts a numeric value that
-         determines the letterspacing factor to be applied to the font
-         size.
-         %
-         E.~g. a kern factor of $0.42$ applied to a $10$ pt font
-         results in $4.2$ pt of additional kerning applied to each
-         pair of glyphs.
-         %
-         Ligatures are split into their component glyphs unless
-         explicitly ignored (see below).
-
-         For compatibility with \XETEX an alternative
-         \identifier{letterspace} option is supplied that interprets the
-         supplied value as a \emphasis{percentage} of the font size but
-         is otherwise identical to \identifier{kernfactor}.
-         %
-         Consequently, both definitions in below snippet yield the same
-         letterspacing width:
-
-         \beginlisting
-    \font \iwonakernedA = "file:Iwona-Regular.otf:kernfactor=0.125"
-    \font \iwonakernedB = "file:Iwona-Regular.otf:letterspace=12.5"
-         \endlisting
-
-         Specific pairs of letters and ligatures may be exempt from
-         letterspacing by defining the \LUA functions
-         \luaident{keeptogether} and \luaident{keepligature},
-         respectively, inside the namespace \inlinecode {luaotfload.letterspace}.
-         %
-         Both functions are called whenever the letterspacing callback
-         encounters an appropriate node or set of nodes.
-         %
-         If they return a true-ish value, no extra kern is inserted at
-         the current position.
-         %
-         \luaident{keeptogether} receives a pair of consecutive
-         glyph nodes in order of their appearance in the node list.
-         %
-         \luaident{keepligature} receives a single node which can be
-         analyzed into components.
-         %
-         (For details refer to the \emphasis{glyph nodes} section in the
-         \LUATEX reference manual.)
-         %
-         The implementation of both functions is left entirely to the
-         user.
-  \endaltitem
-
-\iffalse
-  \startbuffer [printvectors]
-  \directlua{inspect(fonts.protrusions.setups.default)
-             inspect(fonts.expansions.setups.default)}
-  \stopbuffer
-\fi
-
-  \beginaltitem {protrusion \& expansion}
-         These keys control microtypographic features of the font,
-         namely \emphasis{character protrusion} and \emphasis{font
-         expansion}.
-         %
-         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{luaotfload-fonts-ext.lua} where the
-            default values are defined.
-            %
-            Alternatively and with loss of information, you can dump
-            those tables into your terminal by issuing
-            \unless \iffalse
-              \beginlisting
- \directlua{inspect(fonts.protrusions.setups.default)
-            inspect(fonts.expansions.setups.default)}
-              \endlisting
-            \else
-              \typebuffer [printvectors]
-            \fi
-            at some point after loading \fileent{luaotfload.sty}.
-         }
-         %
-         For both, only the set \identifier{default} is predefined.
-
-         For example, to define a font with the default
-         protrusion vector applied\footnote{%
-           You also need to set
-               \inlinecode {pdfprotrudechars=2} and
-               \inlinecode {pdfadjustspacing=2}
-           to activate protrusion and expansion, respectively.
-           See the
-           \hyperlink [\PDFTEX manual]{http://mirrors.ctan.org/systems/pdftex/manual/pdftex-a.pdf}%
-           for details.
-         }:
-
-         \beginlisting
-      \font \test = LatinModernRoman:protrusion=default
-         \endlisting
-  \endaltitem
-\enddescriptions
-
-\endsubsection
-
-\beginsubsection {Non-standard font features}
-\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 (2014) there are three of them:
-
-\begindescriptions
-
-  \beginaltitem {anum}
-          Substitutes the glyphs in the \abbrev{ascii} number range
-          with their counterparts from eastern Arabic or Persian,
-          depending on the value of \identifier{language}.
-  \endaltitem
-
-  \beginaltitem {tlig}
-          Applies legacy \TEX ligatures\footnote{%
-            These contain the feature set \inlinecode {trep} of earlier
-            versions of \identifier{luaotfload}.
-
-            Note to \XETEX users: this is the equivalent of the
-            assignment \inlinecode {mapping=text-tex} using \XETEX's input
-            remapping feature.
-          }:
-
-          \unless \iffalse
-            %% Using braced arg syntax with inline code appears to be
-            %% impossible within Latex tables -- just ignore the weird
-            %% exclamation points below.
-            \begintabulate [rlrl]
-              \beginrow ``  \newcell  {\inlinecode !``! } \newcell  ''  \newcell  {\inlinecode !''!} \endrow
-              \beginrow `   \newcell  {\inlinecode !`!  } \newcell  '   \newcell  {\inlinecode !'! } \endrow
-              \beginrow "   \newcell  {\inlinecode !"!  } \newcell  --  \newcell  {\inlinecode !--!} \endrow
-              \beginrow --- \newcell  {\inlinecode !---!} \newcell  !`  \newcell  {\inlinecode ?!`?} \endrow
-              \beginrow ?`  \newcell  {\inlinecode !?`! } \newcell      \newcell                     \endrow
-            \endtabulate
-          \else
-            %% XXX find a way to wrap these in the tabulate environment
-            \startframed [frame=off,width=broad,align=middle]
-              \startframed [frame=off,width=\dimexpr(\textwidth/2)]
-                \startxtable [align=middle]
-                    \startxrow \startxcell ``  \stopxcell \startxcell  \inlinecode {``}  \stopxcell \startxcell  ''  \stopxcell \startxcell  \inlinecode {''}  \stopxcell \stopxrow
-                    \startxrow \startxcell `   \stopxcell \startxcell  \inlinecode {`}   \stopxcell \startxcell  '   \stopxcell \startxcell  \inlinecode {'}   \stopxcell \stopxrow
-                    \startxrow \startxcell "   \stopxcell \startxcell  \inlinecode {"}   \stopxcell \startxcell  --  \stopxcell \startxcell  \inlinecode {--}  \stopxcell \stopxrow
-                    \startxrow \startxcell --- \stopxcell \startxcell  \inlinecode {---} \stopxcell \startxcell  !`  \stopxcell \startxcell  \inlinecode {!`}  \stopxcell \stopxrow
-                    \startxrow \startxcell ?`  \stopxcell \startxcell  \inlinecode {?`}  \stopxcell \startxcell      \stopxcell \startxcell                    \stopxcell \stopxrow
-                \stopxtable
-              \stopframed
-            \stopframed
-          \fi
-  \endaltitem
-
-  \beginaltitem {itlc}
-          Computes italic correction values (active by default).
-  \endaltitem
-
-\enddescriptions
-
-\endsubsection
-\endsection
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\beginsection {Combining fonts}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-Version 2.7 and later support combining characters from multiple fonts into a
-single virtualized one. This requires that the affected fonts be loaded in
-advance as well as a special \emphasis{request syntax}. Furthermore, this
-allows to define \emphasis{fallback fonts} to supplement fonts that may lack
-certain required glyphs.
-
-Combinations are created by defining a font using the \luaident{combo:} prefix.
-
-\beginsubsection {Fallbacks}
-
-For example, the \identifier{Latin Modern} family of fonts does, as indicated
-in the name, not provide Cyrillic glyphs. If Latin script dominates in the copy
-with interspersed Cyrillic, a fallback can be created from a similiar looking
-font like \identifier{Computer Modern Unicode}, taking advantage of the fact
-that it too derives from Knuth’s original \identifier{Computer Modern} series:
-
-\beginlisting
-  \input luaotfload.sty
-  \font \lm  = file:lmroman10-regular.otf:mode=base
-  \font \cmu = file:cmunrm.otf:mode=base
-  \font \lmu = "combo: 1->\fontid\lm; 2->\fontid\cmu,fallback"
-  \lmu Eh bien, mon prince. Gênes et Lueques ne sont plus que des
-       apanages, des поместья, de la famille Buonaparte.
-  \bye
-\endlisting
-
-As simple as this may look on the first glance, this approach is entirely
-inappropriate if more than a couple letters are required from a different font.
-Because the combination pulls nothing except the glyph data, all of the
-important other information that constitute a proper font -- kerning, styles,
-features, and suchlike -- will be missing.
-
-\endsubsection %% Fallbacks
-
-\beginsubsection {Combinations}
-
-Generalizing the idea of a \emphasis{fallback font}, it is also possible to
-pick definite sets of glyphs from multiple fonts. On a bad day, for instance,
-it may be the sanest choice to start out with \identifier{EB Garamond} italics,
-typeset all decimal digits in the bold italics of \identifier{GNU Freefont},
-and tone down the punctuation with extra thin glyphs from \identifier{Source
-Sans}:
-
-\beginlisting
-  \def \feats     {-tlig;-liga;mode=base;-kern}
-  \def \fileone   {EBGaramond12-Italic.otf}
-  \def \filetwo   {FreeMonoBoldOblique.otf}
-  \def \filethree {SourceSansPro-ExtraLight.otf}
-
-  \input luaotfload.sty
-
-  \font \one   = file:\fileone  :\feats
-  \font \two   = file:\filetwo  :\feats
-  \font \three = file:\filethree:\feats
-
-  \font \onetwothree = "combo:  1 -> \fontid\one;
-                                2 -> \fontid\two,   0x30-0x39;
-                                3 -> \fontid\three, 0x21*0x3f; "
-
-  {\onetwothree \TeX—0123456789—?!}
-  \bye
-\endlisting
-
-\noindent Despite the atrocious result, the example demonstrates well the
-syntax that is used to specify ranges and fonts. Fonts are being referred to by
-their internal index which can be obtained by passing the font command into the
-\texmacro{fontid} macro, e. g. \inlinecode{\fontid\one}, after a font has been
-defined. The first component of the combination is the base font which will be
-extended by the others. It is specified by the index alone.
-
-All further fonts require either the literal \inlinecode{fallback} or a list of
-codepoint definitions to be appended after a comma. The elements of this list
-again denote either single codepoints like \inlinecode{0x21} (referring to the
-exclamation point character) or ranges of codepoints (\inlinecode{0x30-0x39}).
-Elements are separated by the \identifier{ASCII} asterisk character
-(\inlinecode{*}). The characters referenced in the list will be imported from
-the respective font, if available.
-
-\endsubsection %% Combinations
-
-\endsection
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\beginsection {Font names database}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\label{sec:fontdb}
-
-As mentioned above, \identifier{luaotfload} keeps track of which
-fonts are available to \LUATEX by means of a \emphasis{database}.
-%
-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 \hyperlink[\fileent{otfinfo}]{http://www.lcdf.org/type/}
-  (comes with \TEX Live), when invoked on a font file with the
-  \inlinecode {-i} option, lists the variety of name fields defined for
-  it.
-}
-
-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
-recently.
-%
-As soon as the database is updated, the resolver will try
-and look up the font again, all without user intervention.
-%
-The goal is for \identifier{luaotfload} to act in the background and
-behave as unobtrusively as possible, while providing a convenient
-interface to the fonts installed on the system.
-
-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.
-
-\beginsubsection[luaotfload-tool]
-                {\fileent{luaotfload-tool}}
-
-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{luaotfload-tool} that offers an interface to the database
-functionality.
-%
-Being a \LUA script, there are two ways to run it:
-either make it executable (\inlinecode {chmod +x} on unixoid systems) or
-pass it as an argument to \fileent{texlua}.\footnote{%
-  Tests by the maintainer show only marginal performance gain by
-  running with Luigi Scarso’s
-  \hyperlink [\identifier{Luajit\kern-.25ex\TEX}]{https://foundry.supelec.fr/projects/luajittex/},
-  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{luaotfload-tool.exe} or as
-  \inlinecode {texlua.exe luaotfload-tool.lua}.
-}
-%
-Invoked with the argument \inlinecode {--update} it will perform a database
-update, scanning for fonts not indexed.
-
-\beginlisting
-  luaotfload-tool --update
-\endlisting
-
-Adding the \inlinecode {--force} switch will initiate a complete
-rebuild of the database.
-
-\beginlisting
-  luaotfload-tool --update --force
-\endlisting
-
-\endsubsection
-
-\beginsubsection{Search Paths}
-
-\identifier{luaotfload} scans those directories where fonts are
-expected to be located on a given system.
-%
-On a Linux machine it follows the paths listed in the
-\identifier{Fontconfig} configuration files;
-consult \inlinecode {man 5 fonts.conf} for further information.
-%
-On \identifier{Windows} systems, the standard location is
-\inlinecode {Windows\\Fonts},
-%
-while \identifier{Mac OS~X} requires a multitude of paths to
-be examined.
-%
-The complete list is is given in table \ref{table-searchpaths}.
-Other paths can be specified by setting the environment variable
-\inlinecode {OSFONTDIR}.
-%
-If it is non-empty, then search will be extended to the included
-directories.
-
-\tablefloat {table-searchpaths}
-  {List of paths searched for each supported operating system.}
-  {%
-    \unless \iffalse
-      \begincentered
-        \begintabulate [lp{.5\textwidth}]
-          \beginrow
-            Windows   \newcell \inlinecode !\% WINDIR\%\\ Fonts!
-          \endrow
-          \beginrow
-            Linux     \newcell \fileent{/usr/local/etc/fonts/fonts.conf} and\hfill\break
-                               \fileent{/etc/fonts/fonts.conf}
-          \endrow
-          \beginrow
-            Mac       \newcell \fileent{\textasciitilde/Library/Fonts},\break
-                               \fileent{/Library/Fonts},\break
-                               \fileent{/System/Library/Fonts}, and\hfill\break
-                               \fileent{/Network/Library/Fonts}
-          \endrow
-        \endtabulate
-      \endcentered
-    \else
-      \setuplocalinterlinespace [14pt]
-      \starttabulate [|l|p(.5\textwidth)|]
-        \NC Windows   \NC \inlinecode {\% WINDIR\%\\ Fonts} \NC \NR
-        \NC Linux     \NC \fileent{/usr/local/etc/fonts/fonts.conf} and\crlf
-                          \fileent{/etc/fonts/fonts.conf} \NC \NR
-        \NC
-          Mac         \NC \fileent{\textasciitilde/Library/Fonts},\crlf
-                          \fileent{/Library/Fonts},\break
-                          \fileent{/System/Library/Fonts}, and\crlf
-                          \fileent{/Network/Library/Fonts} \NC \NR
-      \stoptabulate
-    \fi%
-  }
-
-\endsubsection
-
-\beginsubsection{Querying from Outside}
-
-\fileent{luaotfload-tool} also provides rudimentary means of
-accessing the information collected in the font database.
-%
-If the option \inlinecode {--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
-
-\beginlisting
-  luaotfload-tool  --find="Iwona Regular"
-\endlisting
-
-\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 add the
-\inlinecode {-F} (or \inlinecode {--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
-
-\beginlisting
-  luaotfload-tool  -F --find="Iwona Bright"
-\endlisting
-
-\noindent
-will tell you that indeed the latter name is correct.
-
-Basic information about fonts in the database can be displayed
-using the \inlinecode {-i} option (\inlinecode {--info}).
-%
-\beginlisting
-  luaotfload-tool  -i --find="Iwona Light Italic"
-\endlisting
-%
-\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}.
-}
-
-For a much more detailed report about a given font try the
-\inlinecode {-I} option instead (\inlinecode {--inspect}).
-\beginlisting
-  luaotfload-tool  -I --find="Iwona Light Italic"
-\endlisting
-
-\inlinecode {luaotfload-tool --help} will list the available command line
-switches, including some not discussed in detail here.
-%
-For a full documentation of \identifier{luaotfload-tool} and its
-capabilities refer to the manpage
-(\inlinecode {man 1 luaotfload-tool}).\footnote{%
-  Or see \inlinecode {luaotfload-tool.rst} in the source directory.
-}
-
-\endsubsection
-
-\beginsubsection {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 \inlinecode {luaotfload-tool -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{luaotfload-blacklist.cnf}.
-
-A blacklist file is a list of font filenames, one per line.
-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 (\inlinecode {\%}) character until the end of the line
-is ignored, so use this to add comments.
-%
-Place this file to some location where the \identifier{kpse}
-library can find it, e.~g.
-\fileent{texmf-local/tex/luatex/luaotfload} if you are running
-\identifier{\TEX Live},\footnote{%
-  You may have to run \inlinecode {mktexlsr} if you created a new file in
-  your \fileent{texmf} tree.
-}
-or just leave it in the working directory of your document.
-%
-\identifier{luaotfload} reads all files named
-\fileent{luaotfload-blacklist.cnf} it finds, so the fonts in
-\fileent{./luaotfload-blacklist.cnf} extend the global blacklist.
-
-Furthermore, a filename prepended with a dash character (\inlinecode{-}) is
-removed from the blacklist, causing it to be temporarily whitelisted
-without modifying the global file.
-%
-An example with explicit paths:
-
-\beginlisting
-% example otf-blacklist.cnf
-/Library/Fonts/GillSans.ttc  % Luaotfload ignores this font.
--/Library/Fonts/Optima.ttc   % This one is usable again, even if
-                             % blacklisted somewhere else.
-\endlisting
-
-\endsubsection
-\endsection
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\beginsection {The Fontloader}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\beginsubsection {Overview}
-
-To a large extent, \identifier{luaotfload} relies on code originally
-written by Hans Hagen for the
-\hyperlink[\identifier{\CONTEXT}]{http://wiki.contextgarden.net}
-format.
-%
-It integrates the font loader, written entirely in \LUA, as distributed
-in the \identifier{\LUATEX-Fonts} package.
-%
-The original \LUA source files have been combined using the \CONTEXT
-packaging library into a single, self-contained blob. In
-this form the font loader depends only on the \identifier{lualibs}
-package and requires only minor adaptions to integrate into
-\identifier{luaotfload}.
-
-The guiding principle is to let \CONTEXT/\LUATEX-Fonts take care of the
-implementation, and update the imported code as frequently as
-necessary.
-%
-As maintainers, we aim at importing files from upstream essentially
-\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
-manually spotted and extracted from the \CONTEXT source code in a
-complicated and error-prone fashion.
-
-\endsubsection
-
-\beginsubsection {Contents and Dependencies}
-
-Below is a commented list of the files distributed with
-\identifier{luaotfload} in one way or the other.
-%
-See figure \ref{file-graph} on page \pageref{file-graph} for a
-graphical representation of the dependencies.
-%
-\label{package}%
-Through the script \fileent{mkimport} a \CONTEXT library
-is invoked to create the \identifier{luaotfload} fontloader as a merged
-(amalgamated) source file.\footnote{%
-  In \CONTEXT, this facility can be accessed by means of a
-  \hyperlink[script]{https://bitbucket.org/phg/context-mirror/src/beta/scripts/context/lua/mtx-package.lua?at=beta}
-  which is integrated into \fileent{mtxrun} as a subcommand.
-  Run \inlinecode {mtxrun --script package --help} to display further
-  information.
-  For the actual merging code see the file
-  \fileent{util-mrg.lua} that is part of \CONTEXT.
-}
-%
-This file constitutes the “default fontloader” and is part of the
-\identifier{luaotfload} package as \fileent{fontloader-YY-MM-DD.lua},
-where the uppercase letters are placeholders for the build date.
-%
-A companion to it, \fileent{luatex-basics-gen.lua} must be loaded
-beforehand to set up parts of the environment required by the \CONTEXT
-libraries.
-%
-During a \TEX\ run, the fontloader initialization and injection happens
-in the module \fileent{luaotfload-init.lua}.
-%
-Additionally, the “reference fontloader” as imported from \LUATEX-Fonts
-is provided as the file \fileent{fontloader-reference.lua}.
-%
-This file is self-contained in that it packages all the auxiliary \LUA
-libraries too, as Luaotfload did up to the 2.5 series; since that job
-has been offloaded to the \identifier{Lualibs} package, loading this
-fontloader introduces a certain code duplication.
-
-A number of \emphasis{\LUA utility libraries} are not part of the
-\identifier{luaotfload} fontloader, contrary to its equivalent in
-\LUATEX-Fonts. These are already provided by the \identifier{lualibs}
-and have thus been omitted from the merge.\footnote{%
-  Faithful listeners will remember the pre-2.6 era when the fontloader
-  used to be integrated as-is which caused all kinds of code
-  duplication with the pervasive \identifier{lualibs} package.
-  This conceptual glitch has since been amended by tightening the
-  coupling with the excellent \CONTEXT\ toolchain.
-}
-
-\begindoublecolumns
-  \begindefinitions
-      \beginaltitem {l-lua.lua}       \endaltitem
-      \beginaltitem {l-lpeg.lua}      \endaltitem
-      \beginaltitem {l-function.lua}  \endaltitem
-      \beginaltitem {l-string.lua}    \endaltitem
-      \beginaltitem {l-table.lua}     \endaltitem
-      \beginaltitem {l-io.lua}        \endaltitem
-      \beginaltitem {l-file.lua}      \endaltitem
-      \beginaltitem {l-boolean.lua}   \endaltitem
-      \beginaltitem {l-math.lua}      \endaltitem
-      \beginaltitem {util-str.lua}    \endaltitem
-      \beginaltitem {util-fil.lua}    \endaltitem
-  \enddefinitions
-\enddoublecolumns
-
-The reference fontloader is home to several \LUA files that can be
-grouped twofold as below:
-
-\begindefinitions
-  \beginnormalitem
-    The \emphasis{font loader} itself.
-    These files have been written for \LUATEX-Fonts and they are
-    distributed along with \identifier{luaotfload} so as to resemble
-    the state of the code when it was imported. Their purpose is either
-    to give a slightly aged version of a file if upstream considers
-    latest developments for not yet ready for use outside Context; or,
-    to install placeholders or minimalist versions of APIs relied upon
-    but usually provided by parts of Context not included in the
-    fontloader.
-    \begindoublecolumns
-      \begindefinitions
-        \beginaltitem{luatex-basics-nod.lua} \endaltitem
-        \beginaltitem{luatex-basics-chr.lua} \endaltitem
-        \beginaltitem{luatex-fonts-enc.lua}  \endaltitem
-        \beginaltitem{luatex-fonts-syn.lua}  \endaltitem
-        \beginaltitem{luatex-fonts-ext.lua}  \endaltitem
-      \enddefinitions
-    \enddoublecolumns
-  \endnormalitem
-
-  \beginnormalitem
-    Code related to \emphasis{font handling and node processing}, taken
-    directly from \CONTEXT.
-    \begindoublecolumns
-      \begindefinitions
-        \beginaltitem{data-con.lua} \endaltitem
-        \beginaltitem{font-ini.lua} \endaltitem
-        \beginaltitem{font-con.lua} \endaltitem
-        \beginaltitem{font-cid.lua} \endaltitem
-        \beginaltitem{font-map.lua} \endaltitem
-        \beginaltitem{font-tfm.lua} \endaltitem
-        \beginaltitem{font-one.lua} \endaltitem
-        \beginaltitem{font-afk.lua} \endaltitem
-        \beginaltitem{font-oti.lua} \endaltitem
-        \beginaltitem{font-otr.lua} \endaltitem
-        \beginaltitem{font-cff.lua} \endaltitem
-        \beginaltitem{font-ttf.lua} \endaltitem
-        \beginaltitem{font-dsp.lua} \endaltitem
-        \beginaltitem{font-oup.lua} \endaltitem
-        \beginaltitem{font-otl.lua} \endaltitem
-        \beginaltitem{font-oto.lua} \endaltitem
-        \beginaltitem{font-otj.lua} \endaltitem
-        \beginaltitem{font-ota.lua} \endaltitem
-        \beginaltitem{font-ots.lua} \endaltitem
-        \beginaltitem{font-osd.lua} \endaltitem
-        \beginaltitem{font-ocl.lua} \endaltitem
-        \beginaltitem{font-lua.lua} \endaltitem
-        \beginaltitem{font-def.lua} \endaltitem
-        \beginaltitem{font-xtx.lua} \endaltitem
-        \beginaltitem{font-gbn.lua} \endaltitem
-      \enddefinitions
-    \enddoublecolumns
-  \endnormalitem
-\enddefinitions
-
-As an alternative to the merged file, \identifier {Luaotfload} may load
-individual unpackaged \LUA libraries that come with the source, or even
-use the files from Context directly.
-%
-Thus if you prefer running bleeding edge code from the \CONTEXT beta,
-choose the \inlinecode {context} fontloader via the configuration file
-(see sections \ref{sec:conf} and \ref{sec:pkg} below).
-
-Also, the merged file at some point loads the Adobe Glyph List from a
-\LUA table that is contained in \fileent{luaotfload-glyphlist.lua},
-which is automatically generated by the script
-\fileent{mkglyphlist}.\footnote{%
-  See \fileent{luaotfload-font-enc.lua}.
-  The hard-coded file name is why we have to replace the procedure
-  that loads the file in \fileent{luaotfload-init.lua}.
-}
-%
-There is a make target \identifier{glyphs} that will create a fresh
-glyph list so we don’t need to import it from \CONTEXT any longer.
-
-In addition to these, \identifier{luaotfload} requires a number of
-files not contained in the merge. Some of these have no equivalent in
-\LUATEX-Fonts or \CONTEXT, some were taken unmodified from the latter.
-
-
-\beginfilelist
-    \beginaltitem {luaotfload-features.lua}
-      font feature handling; incorporates some of the code from
-      \fileent{font-otc} from \CONTEXT;
-    \endaltitem
-    \beginaltitem {luaotfload-configuration.lua}
-      handling of \fileent{luaotfload.conf(5)}.
-    \endaltitem
-    \beginaltitem {luaotfload-log.lua}
-      overrides the \CONTEXT logging functionality.
-    \endaltitem
-    \beginaltitem {luaotfload-loaders.lua}
-      registers readers in the fontloader for various kinds of
-      font formats
-    \endaltitem
-    \beginaltitem {luaotfload-parsers.lua}
-      various \abbrev{lpeg}-based parsers.
-    \endaltitem
-    \beginaltitem {luaotfload-database.lua}
-      font names database.
-    \endaltitem
-    \beginaltitem {luaotfload-resolvers.lua}
-      file name resolvers.
-    \endaltitem
-    \beginaltitem {luaotfload-colors.lua}
-      color handling.
-    \endaltitem
-    \beginaltitem {luaotfload-auxiliary.lua}
-      access to internal functionality for package authors (proposals
-      for additions welcome).
-    \endaltitem
-    \beginaltitem {luaotfload-letterspace.lua}
-      font-based letterspacing.
-    \endaltitem
-\endfilelist
-
-\figurefloat
-  {file-graph}
-  {Schematic of the files in \identifier{Luaotfload}}
-  {filegraph.pdf}
-
-\endsubsection
-
-\beginsubsection {Packaging}
-
-\label{sec:pkg}%
-The fontloader code is integrated as an isolated component that can be
-switched out on demand.
-%
-To specify the fontloader you wish to use, the configuration file
-(described in section \ref{sec:conf}) provides the option
-\inlinecode{fontloader}.
-%
-Its value can be one of the identifiers \inlinecode{default} or
-\inlinecode{reference} (see above, section \ref{package}) or the name
-of a file somewhere in the search path of \LUATEX.
-%
-This will make \identifier {Luaotfload} locate the \CONTEXT source by
-means of \identifier{kpathsea} lookups and use those instead of the
-merged package.
-%
-The parameter may be extended with a path to the \CONTEXT
-\fileent{texmf}, separated with a colon:
-
-\beginlisting
-[run]
-  fontloader = context:~/context/tex/texmf-context
-\endlisting
-
-\noindent This setting allows accessing an installation -- e. g. the
-standalone distribution or a source repository -- outside the current
-\TEX distribution.
-
-Like the \identifier{Lualibs} package, the fontloader is deployed as a
-\emphasis{merged package} containing a series of \LUA files joined
-together in their expected order and stripped of non-significant parts.
-%
-The \fileent{mkimport} utility assists in pulling the files from a
-\CONTEXT tree and packaging them for use with \identifier{Luaotfload}.%
-%
-The state of the files currently in \identifier{Luaotfload}’s
-repository can be queried:
-\beginlisting
-./scripts/mkimport news
-\endlisting
-%
-The subcommand for importing takes the prefix of the desired \CONTEXT
-\identifier{texmf} as an optional argument:
-\beginlisting
-./scripts/mkimport import ~/context/tex/texmf-context
-\endlisting
-%
-Whereas the command for packaging requires a path to the
-\emphasis{package description file} and the output name to be passed.
-\beginlisting
-./scripts/mkimport package fontloader-custom.lua
-\endlisting
-
-From the toplevel makefile, the targets \inlinecode{import} and
-\inlinecode{package} provide easy access to the commands as invoked during
-the \identifier{Luaotfload} build process.\footnote{%
-  \emphasis{Hint for those interested in the packaging process}: issue
-  \inlinecode{make show} for a list of available build routines.
-}
-These will call \inlinecode{mkimport} script with the correct
-parameters to generate a datestamped package.
-%
-Whether files have been updated in the upstream distribution can be
-queried by \inlinecode{./scripts/mkimport news}.
-%
-This will compare the imported files with their counterparts in the
-\CONTEXT distribution and report changes.
-
-\endsubsection
-
-\endsection
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\beginsection {Configuration Files}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\beginnarrower
-  \emphasis{Caution}: For the authoritative documentation, consult the
-  manpage for \fileent{luaotfload.conf(5)}.
-\endnarrower
-
-\label{sec:conf}
-The runtime behavior of \identifier{Luaotfload} can be customized by
-means of a configuration file.
-% location
-At startup, it attempts to locate a file called \fileent
-{luaotfload.conf} or \fileent {luaotfloadrc} at a number of candidate
-locations:
-
-\begincentered
-  \begindefinitions
-    \beginnormalitem \fileent{./luaotfload.conf}                            \endnormalitem
-    \beginnormalitem \fileent{./luaotfloadrc}                               \endnormalitem
-    \beginnormalitem \fileent{\$XDG_CONFIG_HOME/luaotfload/luaotfload.conf} \endnormalitem
-    \beginnormalitem \fileent{\$XDG_CONFIG_HOME/luaotfload/luaotfload.rc}   \endnormalitem
-    \beginnormalitem \fileent{~/.luaotfloadrc}                              \endnormalitem
-  \enddefinitions
-\endcentered
-
-\beginnarrower
-  \emphasis{Caution}: The configuration potentially modifies the final
-  document. A project-local file belongs under version control along
-  with the rest of the document. This is to ensure that everybody who
-  builds the project also receives the same customizations as the
-  author.
-\endnarrower
-
-% syntax
-The syntax is fairly close to the format used by
-\fileent{git-config(1)} which in turn was derived from the popular
-\identifier{.INI} format: Lines of key-value pairs are grouped under
-different configuration “sections”.\footnote{%
-  The configuration parser in \fileent {luoatfload-parsers.lua} might
-  be employed by other packages for similar purposes.
-}
-% example settings
-An example for customization via \fileent {luaotfload.conf} might look
-as below:
-
-\beginlisting
-; Example luaotfload.conf containing a rudimentary configuration
-[db]
-  update-live = false
-[run]
-  color-callback = pre_linebreak_filter
-  definer = info_patch
-  log-level = 5
-[default-features]
-  global = mode=base
-\endlisting
-
-This specifies that for the given project, \identifier{Luaotfload}
-shall not attempt to automatically scan for fonts if it can’t resolve a
-request. The font-based colorization will happen during \LUATEX’s
-pre-linebreak filter. The fontloader will output verbose information
-about the fonts at definition time along with globally increased
-verbosity. Lastly, the fontloader defaults to the less expensive
-\luaident{base} mode like it does in \CONTEXT.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\beginsection {Auxiliary Functions}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-With release version 2.2, \identifier{Luaotfload} received
-additional functions for package authors to call from outside
-(see the file \fileent{luaotfload-auxiliary.lua} for details).
-%
-The purpose of this addition twofold.
-%
-Firstly, \identifier{luaotfload} failed to provide a stable interface
-to internals in the past which resulted in an unmanageable situation
-of different packages abusing the raw access to font objects by means
-of the \luaident{patch_font} callback.
-%
-When the structure of the font object changed due to an update, all
-of these imploded and several packages had to be fixed while
-simultaneously providing fallbacks for earlier versions.
-%
-Now the patching is done on the \identifier{luaotfload} side and can
-be adapted with future modifications to font objects without touching
-the packages that depend on it.
-%
-Second, some the capabilities of the font loader and the names
-database are not immediately relevant in \identifier{luaotfload}
-itself but might nevertheless be of great value to package authors or
-end users.
-
-Note that the current interface is not yet set in stone and the
-development team is open to suggestions for improvements or
-additions.
-
-\beginsubsection {Callback Functions}
-
-The \luaident{patch_font} callback is inserted in the wrapper
-\identifier{luaotfload} provides for the font definition callback.
-%
-At this place it allows manipulating the font object immediately after
-the font loader is done creating it.
-%
-For a short demonstration of its usefulness, here is a snippet that
-writes an entire font object to the file \fileent{fontdump.lua}:
-
-\beginlisting
-  \input luaotfload.sty
-  \directlua{
-    local dumpfile    = "fontdump.lua"
-    local dump_font   = function (tfmdata)
-      local data = table.serialize(tfmdata)
-      io.savedata(dumpfile, data)
-    end
-
-    luatexbase.add_to_callback(
-      "luaotfload.patch_font",
-      dump_font,
-      "my_private_callbacks.dump_font"
-    )
-  }
-  \font \dumpme = name:Iwona
-  \bye
-\endlisting
-
-\emphasis{Beware}: this creates a Lua file of around 150,000 lines of
-code, taking up 3~\abbrev{mb} of disk space.
-%
-By inspecting the output you can get a first impression of how a font
-is structured in \LUATEX’s memory, what elements it is composed of,
-and in what ways it can be rearranged.
-
-\beginsubsubsection {Compatibility with Earlier Versions}
-
-As has been touched on in the preface to this section, the structure
-of the object as returned by the fontloader underwent rather drastic
-changes during different stages of its development, and not all
-packages that made use of font patching have kept up with every one
-of it.
-%
-To ensure compatibility with these as well as older versions of
-some packages, \identifier{luaotfload} sets up copies of or references
-to data in the font table where it used to be located.
-%
-For instance, important parameters like the requested point size, the
-units factor, and the font name have again been made accessible from
-the toplevel of the table even though they were migrated to different
-subtables in the meantime.
-
-\endsubsubsection
-
-\beginsubsubsection{Patches}
-
-These are mostly concerned with establishing compatibility with \XETEX.
-
-\beginfunctionlist
-
-  \beginaltitem  {set_sscale_dimens}
-    Calculate \texmacro{fontdimen}s 10 and 11 to emulate \XETEX.
-  \endaltitem
-
-  \beginaltitem  {set_capheight}
-    Calculates \texmacro{fontdimen} 8 like \XETEX.
-  \endaltitem
-
-  \beginaltitem  {patch_cambria_domh}
-    Correct some values of the font \emphasis{Cambria Math}.
-  \endaltitem
-
-\endfunctionlist
-
-\endsubsection
-
-\beginsubsection {Package Author’s Interface}
-
-As \LUATEX release 1.0 is nearing, the demand for a reliable interface
-for package authors increases.
-
-\endsubsubsection
-
-\beginsubsubsection{Font Properties}
-
-Below functions mostly concern querying the different components of a
-font like for instance the glyphs it contains, or what font features
-are defined for which scripts.
-
-\beginfunctionlist
-
-  \beginaltitem  {aux.font_has_glyph (id : int, index : int)}
-            Predicate that returns true if the font \luaident{id}
-            has glyph \luaident{index}.
-  \endaltitem
-
-  \beginaltitem  {aux.slot_of_name(name : string)}
-            Translates an Adobe Glyph name to the corresponding glyph
-            slot.
-  \endaltitem
-
-  \beginaltitem  {aux.name_of_slot(slot : int)}
-            The inverse of \luaident{slot_of_name}; note that this
-            might be incomplete as multiple glyph names may map to the
-            same codepoint, only one of which is returned by
-            \luaident{name_of_slot}.
-  \endaltitem
-
-  \beginaltitem  {aux.provides_script(id : int, script : string)}
-            Test if a font supports \luaident{script}.
-  \endaltitem
-
-  \beginaltitem  {aux.provides_language(id : int, script : string, language : string)}
-            Test if a font defines \luaident{language} for a given
-            \luaident{script}.
-  \endaltitem
-
-  \beginaltitem  {aux.provides_feature(id : int, script : string,
-             language : string, feature : string)}
-            Test if a font defines \luaident{feature} for
-            \luaident{language} for a given \luaident{script}.
-  \endaltitem
-
-  \beginaltitem  {aux.get_math_dimension(id : int, dimension : string)}
-            Get the dimension \luaident{dimension} of font \luaident{id}.
-  \endaltitem
-
-  \beginaltitem  {aux.sprint_math_dimension(id : int, dimension : string)}
-            Same as \luaident{get_math_dimension()}, but output the value
-            in scaled points at the \TEX end.
-  \endaltitem
-
-\endfunctionlist
-
-\endsubsubsection
-
-\beginsubsubsection{Database}
-
-%% not implemented, may come back later
-\beginfunctionlist
-%   \beginaltitem  {aux.scan_external_dir(dir : string)}
-%             Include fonts in directory \luaident{dir} in font lookups without
-%             adding them to the database.
-%
-  \beginaltitem  {aux.read_font_index (void)}
-            Read the index file from the appropriate location (usually
-            the bytecode file \fileent{luaotfload-names.luc} somewhere
-            in the \fileent{texmf-var} tree) and return the result as a
-            table. The file is processed with each call so it is up to
-            the user to store the result for later access.
-  \endaltitem
-
-  \beginaltitem  {aux.font_index (void)}
-            Return a reference of the font names table used internally
-            by \identifier{luaotfload}. The index will be read if it
-            has not been loaded up to this point. Also a font scan that
-            overwrites the current index file might be triggered. Since
-            the return value points to the actual index, any
-            modifications to the table might influence runtime behavior
-            of \identifier{luaotfload}.
-  \endaltitem
-
-\endfunctionlist
-
-\endsubsubsection
-
-\endsubsection
-\endsection
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\beginsection {Troubleshooting}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\beginsubsection {Database Generation}
-
-If you encounter problems with some fonts, please first update to the
-latest version of this package before reporting a bug, as
-\identifier{luaotfload} is under active development and still a moving
-target.
-%
-The development takes place on \identifier{github} at
-\hyperlink {https://github.com/lualatex/luaotfload} where there is an issue
-tracker for submitting bug reports, feature requests and the likes.
-
-Bug reports are more likely to be addressed if they contain the output
-of
-
-\beginlisting
-    luaotfload-tool --diagnose=environment,files,permissions
-\endlisting
-
-\noindent Consult the man page for a description of these options.
-
-Errors during database generation can be traced by increasing the
-verbosity level and redirecting log output to \fileent{stdout}:
-
-\beginlisting
-    luaotfload-tool -fuvvv --log=stdout
-\endlisting
-
-\noindent or to a file in \fileent{/tmp}:
-
-\beginlisting
-    luaotfload-tool -fuvvv --log=file
-\endlisting
-
-\noindent In the latter case, invoke the \inlinecode {tail(1)} utility on the
-file for live monitoring of the progress.
-
-If database generation fails, the font last printed to the terminal or
-log file is likely to be the culprit.
-%
-Please specify it when reporting a bug, and blacklist it for the time
-being (see above, page \pageref{font-blacklist}).
-
-\endsubsection
-
-\beginsubsection {Font Features}
-
-A common problem is the lack of features for some
-\OpenType fonts even when specified.
-%
-This can be related to the fact that some fonts do not provide features
-for the \inlinecode {dflt} script (see above on page \pageref{script-tag}),
-which is the default one in this package.
-%
-If this happens, assigning a noth script when the font is defined should
-fix it.
-%
-For example with \inlinecode {latn}:
-
-\beginlisting
-    \font \test = file:MyFont.otf:script=latn;+liga;
-\endlisting
-
-You can get a list of features that a font defines for scripts and
-languages by querying it in \fileent{luaotfload-tool}:
-
-\beginlisting
-    luaotfload-tool --find="Iwona" --inspect
-\endlisting
-
-\endsubsection
-
-\beginsubsection {\LUATEX Programming}
-
-Another strategy that helps avoiding problems is to not access raw
-\LUATEX internals directly.
-%
-Some of them, even though they are dangerous to access, have not been
-overridden or disabled.
-%
-Thus, whenever possible prefer the functions in the \luaident{aux}
-namespace over direct manipulation of font objects. For example, raw
-access to the \luaident{font.fonts} table like:
-
-\beginlisting
-    local somefont = font.fonts[2]
-\endlisting
-
-\noindent can render already defined fonts unusable.
-%
-Instead, the function \luaident{font.getfont()} should be used
-because it has been replaced by a safe variant.
-
-However, \luaident{font.getfont()} only covers fonts handled by the
-font loader, e.~g. \identifier{OpenType} and \identifier{TrueType}
-fonts, but not \abbrev{tfm} or \abbrev{ofm}.
-%
-Should you absolutely require access to all fonts known to \LUATEX,
-including the virtual and autogenerated ones, then you need to query
-both \luaident{font.getfont()} and \luaident{font.fonts}.
-%
-In this case, best define you own accessor:
-
-\beginlisting
-    local unsafe_getfont = function (id)
-        local tfmdata = font.getfont (id)
-        if not tfmdata then
-            tfmdata = font.fonts[id]
-        end
-        return tfmdata
-    end
-
-    --- use like getfont()
-    local somefont = unsafe_getfont (2)
-\endlisting
-
-\endsubsection
-\endsection
-
-\beginsection {License}
-
-\identifier {luaotfload} is licensed under the terms of the
-\hyperlink [GNU General Public License version 2.0]%
-           {https://www.gnu.org/licenses/old-licenses/gpl-2.0.html}.
-Following the underlying fontloader code \identifier {luaotfload}
-recognizes only that exact version as its license.
-The „any later version” clause of the original license text as
-copyrighted by the \hyperlink [Free Software Foundation]{http://www.fsf.org/}
-\emphasis {does not apply} to either \identifier {luaotfload} or the
-code imported from \CONTEXT.
-
-The complete text of the license is given as a separate file \fileent
-{COPYING} in the toplevel directory of the
-\hyperlink [\fileent {Luaotfload} Git repository]{https://github.com/lualatex/luaotfload/blob/master/COPYING}.
-Distributions probably package it as \fileent
-{doc/luatex/luaotfload/COPYING} in the relevant \fileent {texmf} tree.
-
-\endsection
-
-\endinput
-
-% vim:ft=tex:tw=79:et:sw=2

Deleted: trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload-tool.rst
===================================================================
(Binary files differ)

Deleted: trunk/Master/texmf-dist/source/luatex/luaotfload/luaotfload.conf.rst
===================================================================
(Binary files differ)

Deleted: trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2017-02-11.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2017-02-11.lua	2018-09-26 20:49:48 UTC (rev 48770)
+++ trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2017-02-11.lua	2018-09-26 20:50:34 UTC (rev 48771)
@@ -1,21726 +0,0 @@
---[[info-----------------------------------------------------------------------
-  Luaotfload fontloader package
-  build 2017-02-11 18:16:05 by phg at phlegethon
--------------------------------------------------------------------------------
-
-  © 2017 PRAGMA ADE / ConTeXt Development Team
-
-  The code in this file is provided under the GPL v2.0 license. See the
-  file COPYING in the Luaotfload repository for details.
-
-  Report bugs to github.com/lualatex/luaotfload
-
-  This file has been assembled from components taken from Context. See
-  the Luaotfload documentation for details:
-
-      $ texdoc luaotfload
-      $ man 1 luaotfload-tool
-      $ man 5 luaotfload.conf
-
-  Included files:
-
-    · fontloader-data-con.lua
-    · fontloader-basics-nod.lua
-    · fontloader-font-ini.lua
-    · fontloader-font-con.lua
-    · fontloader-fonts-enc.lua
-    · fontloader-font-cid.lua
-    · fontloader-font-map.lua
-    · fontloader-font-oti.lua
-    · fontloader-font-otr.lua
-    · fontloader-font-cff.lua
-    · fontloader-font-ttf.lua
-    · fontloader-font-dsp.lua
-    · fontloader-font-oup.lua
-    · fontloader-font-otl.lua
-    · fontloader-font-oto.lua
-    · fontloader-font-otj.lua
-    · fontloader-font-ota.lua
-    · fontloader-font-ots.lua
-    · fontloader-font-osd.lua
-    · fontloader-font-ocl.lua
-    · fontloader-font-otc.lua
-    · fontloader-font-onr.lua
-    · fontloader-font-one.lua
-    · fontloader-font-afk.lua
-    · fontloader-font-tfm.lua
-    · fontloader-font-lua.lua
-    · fontloader-font-def.lua
-    · fontloader-fonts-ext.lua
-    · fontloader-font-gbn.lua
-
---info]]-----------------------------------------------------------------------
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “data-con” d8982c834ed9acc6193eee23067b9d5d] ---
-
-if not modules then modules={} end modules ['data-con']={
-  version=1.100,
-  comment="companion to luat-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local format,lower,gsub=string.format,string.lower,string.gsub
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
-local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
-local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
-containers=containers or {}
-local containers=containers
-containers.usecache=true
-local report_containers=logs.reporter("resolvers","containers")
-local allocated={}
-local mt={
-  __index=function(t,k)
-    if k=="writable" then
-      local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
-      t.writable=writable
-      return writable
-    elseif k=="readables" then
-      local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
-      t.readables=readables
-      return readables
-    end
-  end,
-  __storage__=true
-}
-function containers.define(category,subcategory,version,enabled)
-  if category and subcategory then
-    local c=allocated[category]
-    if not c then
-      c={}
-      allocated[category]=c
-    end
-    local s=c[subcategory]
-    if not s then
-      s={
-        category=category,
-        subcategory=subcategory,
-        storage={},
-        enabled=enabled,
-        version=version or math.pi,
-        trace=false,
-      }
-      setmetatable(s,mt)
-      c[subcategory]=s
-    end
-    return s
-  end
-end
-function containers.is_usable(container,name)
-  return container.enabled and caches and caches.is_writable(container.writable,name)
-end
-function containers.is_valid(container,name)
-  if name and name~="" then
-    local storage=container.storage[name]
-    return storage and storage.cache_version==container.version
-  else
-    return false
-  end
-end
-function containers.read(container,name)
-  local storage=container.storage
-  local stored=storage[name]
-  if not stored and container.enabled and caches and containers.usecache then
-    stored=caches.loaddata(container.readables,name,container.writable)
-    if stored and stored.cache_version==container.version then
-      if trace_cache or trace_containers then
-        report_containers("action %a, category %a, name %a","load",container.subcategory,name)
-      end
-    else
-      stored=nil
-    end
-    storage[name]=stored
-  elseif stored then
-    if trace_cache or trace_containers then
-      report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
-    end
-  end
-  return stored
-end
-function containers.write(container,name,data)
-  if data then
-    data.cache_version=container.version
-    if container.enabled and caches then
-      local unique,shared=data.unique,data.shared
-      data.unique,data.shared=nil,nil
-      caches.savedata(container.writable,name,data)
-      if trace_cache or trace_containers then
-        report_containers("action %a, category %a, name %a","save",container.subcategory,name)
-      end
-      data.unique,data.shared=unique,shared
-    end
-    if trace_cache or trace_containers then
-      report_containers("action %a, category %a, name %a","store",container.subcategory,name)
-    end
-    container.storage[name]=data
-  end
-  return data
-end
-function containers.content(container,name)
-  return container.storage[name]
-end
-function containers.cleanname(name)
-  return (gsub(lower(name),"[^%w\128-\255]+","-")) 
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “data-con”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “basics-nod” 9288471b8395bfb683aba0ff3964d950] ---
-
-if not modules then modules={} end modules ['luatex-fonts-nod']={
-  version=1.001,
-  comment="companion to luatex-fonts.lua",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-if context then
-  texio.write_nl("fatal error: this module is not for context")
-  os.exit()
-end
-if tex.attribute[0]~=0 then
-  texio.write_nl("log","!")
-  texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be")
-  texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special")
-  texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.")
-  texio.write_nl("log","!")
-  tex.attribute[0]=0 
-end
-attributes=attributes or {}
-attributes.unsetvalue=-0x7FFFFFFF
-local numbers,last={},127
-attributes.private=attributes.private or function(name)
-  local number=numbers[name]
-  if not number then
-    if last<255 then
-      last=last+1
-    end
-    number=last
-    numbers[name]=number
-  end
-  return number
-end
-nodes={}
-nodes.pool={}
-nodes.handlers={}
-local nodecodes={}
-local glyphcodes=node.subtypes("glyph")
-local disccodes=node.subtypes("disc")
-for k,v in next,node.types() do
-  v=string.gsub(v,"_","")
-  nodecodes[k]=v
-  nodecodes[v]=k
-end
-for i=0,#glyphcodes do
-  glyphcodes[glyphcodes[i]]=i
-end
-for i=0,#disccodes do
-  disccodes[disccodes[i]]=i
-end
-nodes.nodecodes=nodecodes
-nodes.glyphcodes=glyphcodes
-nodes.disccodes=disccodes
-local flush_node=node.flush_node
-local remove_node=node.remove
-local new_node=node.new
-local traverse_id=node.traverse_id
-nodes.handlers.protectglyphs=node.protect_glyphs
-nodes.handlers.unprotectglyphs=node.unprotect_glyphs
-local math_code=nodecodes.math
-local end_of_math=node.end_of_math
-function node.end_of_math(n)
-  if n.id==math_code and n.subtype==1 then
-    return n
-  else
-    return end_of_math(n)
-  end
-end
-function nodes.remove(head,current,free_too)
-  local t=current
-  head,current=remove_node(head,current)
-  if t then
-    if free_too then
-      flush_node(t)
-      t=nil
-    else
-      t.next,t.prev=nil,nil
-    end
-  end
-  return head,current,t
-end
-function nodes.delete(head,current)
-  return nodes.remove(head,current,true)
-end
-function nodes.pool.kern(k)
-  local n=new_node("kern",1)
-  n.kern=k
-  return n
-end
-local getfield=node.getfield
-local setfield=node.setfield
-nodes.getfield=getfield
-nodes.setfield=setfield
-nodes.getattr=getfield
-nodes.setattr=setfield
-nodes.tostring=node.tostring or tostring
-nodes.copy=node.copy
-nodes.copy_node=node.copy
-nodes.copy_list=node.copy_list
-nodes.delete=node.delete
-nodes.dimensions=node.dimensions
-nodes.end_of_math=node.end_of_math
-nodes.flush_list=node.flush_list
-nodes.flush_node=node.flush_node
-nodes.flush=node.flush_node
-nodes.free=node.free
-nodes.insert_after=node.insert_after
-nodes.insert_before=node.insert_before
-nodes.hpack=node.hpack
-nodes.new=node.new
-nodes.tail=node.tail
-nodes.traverse=node.traverse
-nodes.traverse_id=node.traverse_id
-nodes.slide=node.slide
-nodes.vpack=node.vpack
-nodes.first_glyph=node.first_glyph
-nodes.has_glyph=node.has_glyph or node.first_glyph
-nodes.current_attr=node.current_attr
-nodes.has_field=node.has_field
-nodes.last_node=node.last_node
-nodes.usedlist=node.usedlist
-nodes.protrusion_skippable=node.protrusion_skippable
-nodes.write=node.write
-nodes.has_attribute=node.has_attribute
-nodes.set_attribute=node.set_attribute
-nodes.unset_attribute=node.unset_attribute
-nodes.protect_glyphs=node.protect_glyphs
-nodes.unprotect_glyphs=node.unprotect_glyphs
-nodes.mlist_to_hlist=node.mlist_to_hlist
-local direct=node.direct
-local nuts={}
-nodes.nuts=nuts
-local tonode=direct.tonode
-local tonut=direct.todirect
-nodes.tonode=tonode
-nodes.tonut=tonut
-nuts.tonode=tonode
-nuts.tonut=tonut
-local getfield=direct.getfield
-local setfield=direct.setfield
-nuts.getfield=getfield
-nuts.setfield=setfield
-nuts.getnext=direct.getnext
-nuts.setnext=direct.setnext
-nuts.getprev=direct.getprev
-nuts.setprev=direct.setprev
-nuts.getboth=direct.getboth
-nuts.setboth=direct.setboth
-nuts.getid=direct.getid
-nuts.getattr=direct.get_attribute or direct.has_attribute or getfield
-nuts.setattr=setfield
-nuts.getfont=direct.getfont
-nuts.setfont=direct.setfont
-nuts.getsubtype=direct.getsubtype
-nuts.setsubtype=direct.setsubtype or function(n,s) setfield(n,"subtype",s) end
-nuts.getchar=direct.getchar
-nuts.setchar=direct.setchar
-nuts.getdisc=direct.getdisc
-nuts.setdisc=direct.setdisc
-nuts.setlink=direct.setlink
-nuts.getlist=direct.getlist
-nuts.setlist=direct.setlist  or function(n,l) setfield(n,"list",l) end
-nuts.getleader=direct.getleader
-nuts.setleader=direct.setleader or function(n,l) setfield(n,"leader",l) end
-if not direct.is_glyph then
-  local getchar=direct.getchar
-  local getid=direct.getid
-  local getfont=direct.getfont
-  local glyph_code=nodes.nodecodes.glyph
-  function direct.is_glyph(n,f)
-    local id=getid(n)
-    if id==glyph_code then
-      if f and getfont(n)==f then
-        return getchar(n)
-      else
-        return false
-      end
-    else
-      return nil,id
-    end
-  end
-  function direct.is_char(n,f)
-    local id=getid(n)
-    if id==glyph_code then
-      if getsubtype(n)>=256 then
-        return false
-      elseif f and getfont(n)==f then
-        return getchar(n)
-      else
-        return false
-      end
-    else
-      return nil,id
-    end
-  end
-end
-nuts.ischar=direct.is_char
-nuts.is_char=direct.is_char
-nuts.isglyph=direct.is_glyph
-nuts.is_glyph=direct.is_glyph
-nuts.insert_before=direct.insert_before
-nuts.insert_after=direct.insert_after
-nuts.delete=direct.delete
-nuts.copy=direct.copy
-nuts.copy_node=direct.copy
-nuts.copy_list=direct.copy_list
-nuts.tail=direct.tail
-nuts.flush_list=direct.flush_list
-nuts.flush_node=direct.flush_node
-nuts.flush=direct.flush
-nuts.free=direct.free
-nuts.remove=direct.remove
-nuts.is_node=direct.is_node
-nuts.end_of_math=direct.end_of_math
-nuts.traverse=direct.traverse
-nuts.traverse_id=direct.traverse_id
-nuts.traverse_char=direct.traverse_char
-nuts.ligaturing=direct.ligaturing
-nuts.kerning=direct.kerning
-nuts.getprop=nuts.getattr
-nuts.setprop=nuts.setattr
-local new_nut=direct.new
-nuts.new=new_nut
-nuts.pool={}
-function nuts.pool.kern(k)
-  local n=new_nut("kern",1)
-  setfield(n,"kern",k)
-  return n
-end
-local propertydata=direct.get_properties_table()
-nodes.properties={ data=propertydata }
-direct.set_properties_mode(true,true)   
-function direct.set_properties_mode() end 
-nuts.getprop=function(n,k)
-  local p=propertydata[n]
-  if p then
-    return p[k]
-  end
-end
-nuts.setprop=function(n,k,v)
-  if v then
-    local p=propertydata[n]
-    if p then
-      p[k]=v
-    else
-      propertydata[n]={ [k]=v }
-    end
-  end
-end
-nodes.setprop=nodes.setproperty
-nodes.getprop=nodes.getproperty
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “basics-nod”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-ini” 10cb9a563a98e06ff79c35a8751e13dc] ---
-
-if not modules then modules={} end modules ['font-ini']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local allocate=utilities.storage.allocate
-fonts=fonts or {}
-local fonts=fonts
-fonts.hashes={ identifiers=allocate() }
-fonts.tables=fonts.tables   or {}
-fonts.helpers=fonts.helpers  or {}
-fonts.tracers=fonts.tracers  or {} 
-fonts.specifiers=fonts.specifiers or {} 
-fonts.analyzers={} 
-fonts.readers={}
-fonts.definers={ methods={} }
-fonts.loggers={ register=function() end }
-fontloader.totable=fontloader.to_table 
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-ini”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-con” 7575a7b4e6d04816072945e27d7d0b33] ---
-
-if not modules then modules={} end modules ['font-con']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local next,tostring,rawget=next,tostring,rawget
-local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find
-local sort,insert,concat,sortedkeys,serialize,fastcopy=table.sort,table.insert,table.concat,table.sortedkeys,table.serialize,table.fastcopy
-local derivetable=table.derive
-local ioflush=io.flush
-local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
-local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end)
-local report_defining=logs.reporter("fonts","defining")
-local fonts=fonts
-local constructors=fonts.constructors or {}
-fonts.constructors=constructors
-local handlers=fonts.handlers or {} 
-fonts.handlers=handlers
-local allocate=utilities.storage.allocate
-local setmetatableindex=table.setmetatableindex
-constructors.dontembed=allocate()
-constructors.autocleanup=true
-constructors.namemode="fullpath" 
-constructors.version=1.01
-constructors.cache=containers.define("fonts","constructors",constructors.version,false)
-constructors.privateoffset=0xF0000 
-constructors.cacheintex=true
-local designsizes=allocate()
-constructors.designsizes=designsizes
-local loadedfonts=allocate()
-constructors.loadedfonts=loadedfonts
-local factors={
-  pt=65536.0,
-  bp=65781.8,
-}
-function constructors.setfactor(f)
-  constructors.factor=factors[f or 'pt'] or factors.pt
-end
-constructors.setfactor()
-function constructors.scaled(scaledpoints,designsize) 
-  if scaledpoints<0 then
-    local factor=constructors.factor
-    if designsize then
-      if designsize>factor then 
-        return (- scaledpoints/1000)*designsize 
-      else
-        return (- scaledpoints/1000)*designsize*factor
-      end
-    else
-      return (- scaledpoints/1000)*10*factor
-    end
-  else
-    return scaledpoints
-  end
-end
-function constructors.cleanuptable(tfmdata)
-  if constructors.autocleanup and tfmdata.properties.virtualized then
-    for k,v in next,tfmdata.characters do
-      if v.commands then v.commands=nil end
-    end
-  end
-end
-function constructors.calculatescale(tfmdata,scaledpoints)
-  local parameters=tfmdata.parameters
-  if scaledpoints<0 then
-    scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize) 
-  end
-  return scaledpoints,scaledpoints/(parameters.units or 1000) 
-end
-local unscaled={
-  ScriptPercentScaleDown=true,
-  ScriptScriptPercentScaleDown=true,
-  RadicalDegreeBottomRaisePercent=true,
-  NoLimitSupFactor=true,
-  NoLimitSubFactor=true,
-}
-function constructors.assignmathparameters(target,original)
-  local mathparameters=original.mathparameters
-  if mathparameters and next(mathparameters) then
-    local targetparameters=target.parameters
-    local targetproperties=target.properties
-    local targetmathparameters={}
-    local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor
-    for name,value in next,mathparameters do
-      if unscaled[name] then
-        targetmathparameters[name]=value
-      else
-        targetmathparameters[name]=value*factor
-      end
-    end
-    if not targetmathparameters.FractionDelimiterSize then
-      targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size
-    end
-    if not mathparameters.FractionDelimiterDisplayStyleSize then
-      targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size
-    end
-    target.mathparameters=targetmathparameters
-  end
-end
-function constructors.beforecopyingcharacters(target,original)
-end
-function constructors.aftercopyingcharacters(target,original)
-end
-constructors.sharefonts=false
-constructors.nofsharedfonts=0
-local sharednames={}
-function constructors.trytosharefont(target,tfmdata)
-  if constructors.sharefonts then 
-    local characters=target.characters
-    local n=1
-    local t={ target.psname }
-    local u=sortedkeys(characters)
-    for i=1,#u do
-      local k=u[i]
-      n=n+1;t[n]=k
-      n=n+1;t[n]=characters[k].index or k
-    end
-    local h=md5.HEX(concat(t," "))
-    local s=sharednames[h]
-    if s then
-      if trace_defining then
-        report_defining("font %a uses backend resources of font %a",target.fullname,s)
-      end
-      target.fullname=s
-      constructors.nofsharedfonts=constructors.nofsharedfonts+1
-      target.properties.sharedwith=s
-    else
-      sharednames[h]=target.fullname
-    end
-  end
-end
-function constructors.enhanceparameters(parameters)
-  local xheight=parameters.x_height
-  local quad=parameters.quad
-  local space=parameters.space
-  local stretch=parameters.space_stretch
-  local shrink=parameters.space_shrink
-  local extra=parameters.extra_space
-  local slant=parameters.slant
-  parameters.xheight=xheight
-  parameters.spacestretch=stretch
-  parameters.spaceshrink=shrink
-  parameters.extraspace=extra
-  parameters.em=quad
-  parameters.ex=xheight
-  parameters.slantperpoint=slant
-  parameters.spacing={
-    width=space,
-    stretch=stretch,
-    shrink=shrink,
-    extra=extra,
-  }
-end
-local function mathkerns(v,vdelta)
-  local k={}
-  for i=1,#v do
-    local entry=v[i]
-    local height=entry.height
-    local kern=entry.kern
-    k[i]={
-      height=height and vdelta*height or 0,
-      kern=kern  and vdelta*kern  or 0,
-    }
-  end
-  return k
-end
-local psfake=0
-local function fixedpsname(psname,fallback)
-  local usedname=psname
-  if psname and psname~="" then
-    if find(psname," ") then
-      usedname=gsub(psname,"[%s]+","-")
-    else
-    end
-  elseif not fallback or fallback=="" then
-    psfake=psfake+1
-    psname="fakename-"..psfake
-  else
-    psname=fallback
-    usedname=gsub(psname,"[^a-zA-Z0-9]+","-")
-  end
-  return usedname,psname~=usedname
-end
-function constructors.scale(tfmdata,specification)
-  local target={}
-  if tonumber(specification) then
-    specification={ size=specification }
-  end
-  target.specification=specification
-  local scaledpoints=specification.size
-  local relativeid=specification.relativeid
-  local properties=tfmdata.properties   or {}
-  local goodies=tfmdata.goodies    or {}
-  local resources=tfmdata.resources   or {}
-  local descriptions=tfmdata.descriptions  or {} 
-  local characters=tfmdata.characters   or {} 
-  local changed=tfmdata.changed    or {} 
-  local shared=tfmdata.shared     or {}
-  local parameters=tfmdata.parameters   or {}
-  local mathparameters=tfmdata.mathparameters or {}
-  local targetcharacters={}
-  local targetdescriptions=derivetable(descriptions)
-  local targetparameters=derivetable(parameters)
-  local targetproperties=derivetable(properties)
-  local targetgoodies=goodies            
-  target.characters=targetcharacters
-  target.descriptions=targetdescriptions
-  target.parameters=targetparameters
-  target.properties=targetproperties
-  target.goodies=targetgoodies
-  target.shared=shared
-  target.resources=resources
-  target.unscaled=tfmdata
-  local mathsize=tonumber(specification.mathsize) or 0
-  local textsize=tonumber(specification.textsize) or scaledpoints
-  local forcedsize=tonumber(parameters.mathsize  ) or 0
-  local extrafactor=tonumber(specification.factor ) or 1
-  if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then
-    scaledpoints=parameters.scriptpercentage*textsize/100
-  elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then
-    scaledpoints=parameters.scriptscriptpercentage*textsize/100
-  elseif forcedsize>1000 then 
-    scaledpoints=forcedsize
-  end
-  targetparameters.mathsize=mathsize  
-  targetparameters.textsize=textsize  
-  targetparameters.forcedsize=forcedsize 
-  targetparameters.extrafactor=extrafactor
-  local tounicode=fonts.mappings.tounicode
-  local defaultwidth=resources.defaultwidth or 0
-  local defaultheight=resources.defaultheight or 0
-  local defaultdepth=resources.defaultdepth or 0
-  local units=parameters.units or 1000
-  if target.fonts then
-    target.fonts=fastcopy(target.fonts) 
-  end
-  targetproperties.language=properties.language or "dflt" 
-  targetproperties.script=properties.script  or "dflt" 
-  targetproperties.mode=properties.mode   or "base"
-  local askedscaledpoints=scaledpoints
-  local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification)
-  local hdelta=delta
-  local vdelta=delta
-  target.designsize=parameters.designsize 
-  target.units=units
-  target.units_per_em=units
-  local direction=properties.direction or tfmdata.direction or 0 
-  target.direction=direction
-  properties.direction=direction
-  target.size=scaledpoints
-  target.encodingbytes=properties.encodingbytes or 1
-  target.embedding=properties.embedding or "subset"
-  target.tounicode=1
-  target.cidinfo=properties.cidinfo
-  target.format=properties.format
-  target.cache=constructors.cacheintex and "yes" or "renew"
-  local fontname=properties.fontname or tfmdata.fontname
-  local fullname=properties.fullname or tfmdata.fullname
-  local filename=properties.filename or tfmdata.filename
-  local psname=properties.psname  or tfmdata.psname
-  local name=properties.name   or tfmdata.name
-  local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename))
-  target.fontname=fontname
-  target.fullname=fullname
-  target.filename=filename
-  target.psname=psname
-  target.name=name
-  properties.fontname=fontname
-  properties.fullname=fullname
-  properties.filename=filename
-  properties.psname=psname
-  properties.name=name
-  local expansion=parameters.expansion
-  if expansion then
-    target.stretch=expansion.stretch
-    target.shrink=expansion.shrink
-    target.step=expansion.step
-    target.auto_expand=expansion.auto
-  end
-  local protrusion=parameters.protrusion
-  if protrusion then
-    target.auto_protrude=protrusion.auto
-  end
-  local extendfactor=parameters.extendfactor or 0
-  if extendfactor~=0 and extendfactor~=1 then
-    hdelta=hdelta*extendfactor
-    target.extend=extendfactor*1000 
-  else
-    target.extend=1000 
-  end
-  local slantfactor=parameters.slantfactor or 0
-  if slantfactor~=0 then
-    target.slant=slantfactor*1000
-  else
-    target.slant=0
-  end
-  targetparameters.factor=delta
-  targetparameters.hfactor=hdelta
-  targetparameters.vfactor=vdelta
-  targetparameters.size=scaledpoints
-  targetparameters.units=units
-  targetparameters.scaledpoints=askedscaledpoints
-  local isvirtual=properties.virtualized or tfmdata.type=="virtual"
-  local hasquality=target.auto_expand or target.auto_protrude
-  local hasitalics=properties.hasitalics
-  local autoitalicamount=properties.autoitalicamount
-  local stackmath=not properties.nostackmath
-  local nonames=properties.noglyphnames
-  local haskerns=properties.haskerns   or properties.mode=="base" 
-  local hasligatures=properties.hasligatures or properties.mode=="base" 
-  local realdimensions=properties.realdimensions
-  local writingmode=properties.writingmode or "horizontal"
-  local identity=properties.identity or "horizontal"
-  if changed and not next(changed) then
-    changed=false
-  end
-  target.type=isvirtual and "virtual" or "real"
-  target.writingmode=writingmode=="vertical" and "vertical" or "horizontal"
-  target.identity=identity=="vertical" and "vertical" or "horizontal"
-  target.postprocessors=tfmdata.postprocessors
-  local targetslant=(parameters.slant     or parameters[1] or 0)*factors.pt 
-  local targetspace=(parameters.space     or parameters[2] or 0)*hdelta
-  local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta
-  local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta
-  local targetx_height=(parameters.x_height   or parameters[5] or 0)*vdelta
-  local targetquad=(parameters.quad     or parameters[6] or 0)*hdelta
-  local targetextra_space=(parameters.extra_space  or parameters[7] or 0)*hdelta
-  targetparameters.slant=targetslant 
-  targetparameters.space=targetspace
-  targetparameters.space_stretch=targetspace_stretch
-  targetparameters.space_shrink=targetspace_shrink
-  targetparameters.x_height=targetx_height
-  targetparameters.quad=targetquad
-  targetparameters.extra_space=targetextra_space
-  local ascender=parameters.ascender
-  if ascender then
-    targetparameters.ascender=delta*ascender
-  end
-  local descender=parameters.descender
-  if descender then
-    targetparameters.descender=delta*descender
-  end
-  constructors.enhanceparameters(targetparameters)
-  local protrusionfactor=(targetquad~=0 and 1000/targetquad) or 0
-  local scaledwidth=defaultwidth*hdelta
-  local scaledheight=defaultheight*vdelta
-  local scaleddepth=defaultdepth*vdelta
-  local hasmath=(properties.hasmath or next(mathparameters)) and true
-  if hasmath then
-    constructors.assignmathparameters(target,tfmdata) 
-    properties.hasmath=true
-    target.nomath=false
-    target.MathConstants=target.mathparameters
-  else
-    properties.hasmath=false
-    target.nomath=true
-    target.mathparameters=nil 
-  end
-  if hasmath then
-    local mathitalics=properties.mathitalics
-    if mathitalics==false then
-      if trace_defining then
-        report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename)
-      end
-      hasitalics=false
-      autoitalicamount=false
-    end
-  else
-    local textitalics=properties.textitalics
-    if textitalics==false then
-      if trace_defining then
-        report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename)
-      end
-      hasitalics=false
-      autoitalicamount=false
-    end
-  end
-  if trace_defining then
-    report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a",
-      name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta,
-      hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled")
-  end
-  constructors.beforecopyingcharacters(target,tfmdata)
-  local sharedkerns={}
-  for unicode,character in next,characters do
-    local chr,description,index
-    if changed then
-      local c=changed[unicode]
-      if c then
-        description=descriptions[c] or descriptions[unicode] or character
-        character=characters[c] or character
-        index=description.index or c
-      else
-        description=descriptions[unicode] or character
-        index=description.index or unicode
-      end
-    else
-      description=descriptions[unicode] or character
-      index=description.index or unicode
-    end
-    local width=description.width
-    local height=description.height
-    local depth=description.depth
-    if realdimensions then
-      if not height or height==0 then
-        local bb=description.boundingbox
-        local ht=bb[4]
-        if ht~=0 then
-          height=ht
-        end
-        if not depth or depth==0 then
-          local dp=-bb[2]
-          if dp~=0 then
-            depth=dp
-          end
-        end
-      elseif not depth or depth==0 then
-        local dp=-description.boundingbox[2]
-        if dp~=0 then
-          depth=dp
-        end
-      end
-    end
-    if width then width=hdelta*width else width=scaledwidth end
-    if height then height=vdelta*height else height=scaledheight end
-    if depth and depth~=0 then
-      depth=delta*depth
-      if nonames then
-        chr={
-          index=index,
-          height=height,
-          depth=depth,
-          width=width,
-        }
-      else
-        chr={
-          name=description.name,
-          index=index,
-          height=height,
-          depth=depth,
-          width=width,
-        }
-      end
-    else
-      if nonames then
-        chr={
-          index=index,
-          height=height,
-          width=width,
-        }
-      else
-        chr={
-          name=description.name,
-          index=index,
-          height=height,
-          width=width,
-        }
-      end
-    end
-    local isunicode=description.unicode
-    if isunicode then
-      chr.unicode=isunicode
-      chr.tounicode=tounicode(isunicode)
-    end
-    if hasquality then
-      local ve=character.expansion_factor
-      if ve then
-        chr.expansion_factor=ve*1000 
-      end
-      local vl=character.left_protruding
-      if vl then
-        chr.left_protruding=protrusionfactor*width*vl
-      end
-      local vr=character.right_protruding
-      if vr then
-        chr.right_protruding=protrusionfactor*width*vr
-      end
-    end
-    if hasmath then
-      local vn=character.next
-      if vn then
-        chr.next=vn
-      else
-        local vv=character.vert_variants
-        if vv then
-          local t={}
-          for i=1,#vv do
-            local vvi=vv[i]
-            t[i]={
-              ["start"]=(vvi["start"]  or 0)*vdelta,
-              ["end"]=(vvi["end"]   or 0)*vdelta,
-              ["advance"]=(vvi["advance"] or 0)*vdelta,
-              ["extender"]=vvi["extender"],
-              ["glyph"]=vvi["glyph"],
-            }
-          end
-          chr.vert_variants=t
-        else
-          local hv=character.horiz_variants
-          if hv then
-            local t={}
-            for i=1,#hv do
-              local hvi=hv[i]
-              t[i]={
-                ["start"]=(hvi["start"]  or 0)*hdelta,
-                ["end"]=(hvi["end"]   or 0)*hdelta,
-                ["advance"]=(hvi["advance"] or 0)*hdelta,
-                ["extender"]=hvi["extender"],
-                ["glyph"]=hvi["glyph"],
-              }
-            end
-            chr.horiz_variants=t
-          end
-        end
-      end
-      local vi=character.vert_italic
-      if vi and vi~=0 then
-        chr.vert_italic=vi*hdelta
-      end
-      local va=character.accent
-      if va then
-        chr.top_accent=vdelta*va
-      end
-      if stackmath then
-        local mk=character.mathkerns
-        if mk then
-          local tr,tl,br,bl=mk.topright,mk.topleft,mk.bottomright,mk.bottomleft
-          chr.mathkern={ 
-            top_right=tr and mathkerns(tr,vdelta) or nil,
-            top_left=tl and mathkerns(tl,vdelta) or nil,
-            bottom_right=br and mathkerns(br,vdelta) or nil,
-            bottom_left=bl and mathkerns(bl,vdelta) or nil,
-          }
-        end
-      end
-      if hasitalics then
-        local vi=character.italic
-        if vi and vi~=0 then
-          chr.italic=vi*hdelta
-        end
-      end
-    elseif autoitalicamount then 
-      local vi=description.italic
-      if not vi then
-        local bb=description.boundingbox
-        if bb then
-          local vi=bb[3]-description.width+autoitalicamount
-          if vi>0 then 
-            chr.italic=vi*hdelta
-          end
-        else
-        end
-      elseif vi~=0 then
-        chr.italic=vi*hdelta
-      end
-    elseif hasitalics then 
-      local vi=character.italic
-      if vi and vi~=0 then
-        chr.italic=vi*hdelta
-      end
-    end
-    if haskerns then
-      local vk=character.kerns
-      if vk then
-        local s=sharedkerns[vk]
-        if not s then
-          s={}
-          for k,v in next,vk do s[k]=v*hdelta end
-          sharedkerns[vk]=s
-        end
-        chr.kerns=s
-      end
-    end
-    if hasligatures then
-      local vl=character.ligatures
-      if vl then
-        if true then
-          chr.ligatures=vl 
-        else
-          local tt={}
-          for i,l in next,vl do
-            tt[i]=l
-          end
-          chr.ligatures=tt
-        end
-      end
-    end
-    if isvirtual then
-      local vc=character.commands
-      if vc then
-        local ok=false
-        for i=1,#vc do
-          local key=vc[i][1]
-          if key=="right" or key=="down" then
-            ok=true
-            break
-          end
-        end
-        if ok then
-          local tt={}
-          for i=1,#vc do
-            local ivc=vc[i]
-            local key=ivc[1]
-            if key=="right" then
-              tt[i]={ key,ivc[2]*hdelta }
-            elseif key=="down" then
-              tt[i]={ key,ivc[2]*vdelta }
-            elseif key=="rule" then
-              tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta }
-            else 
-              tt[i]=ivc 
-            end
-          end
-          chr.commands=tt
-        else
-          chr.commands=vc
-        end
-        chr.index=nil
-      end
-    end
-    targetcharacters[unicode]=chr
-  end
-  properties.setitalics=hasitalics
-  constructors.aftercopyingcharacters(target,tfmdata)
-  constructors.trytosharefont(target,tfmdata)
-  return target
-end
-function constructors.finalize(tfmdata)
-  if tfmdata.properties and tfmdata.properties.finalized then
-    return
-  end
-  if not tfmdata.characters then
-    return nil
-  end
-  if not tfmdata.goodies then
-    tfmdata.goodies={} 
-  end
-  local parameters=tfmdata.parameters
-  if not parameters then
-    return nil
-  end
-  if not parameters.expansion then
-    parameters.expansion={
-      stretch=tfmdata.stretch   or 0,
-      shrink=tfmdata.shrink   or 0,
-      step=tfmdata.step    or 0,
-      auto=tfmdata.auto_expand or false,
-    }
-  end
-  if not parameters.protrusion then
-    parameters.protrusion={
-      auto=auto_protrude
-    }
-  end
-  if not parameters.size then
-    parameters.size=tfmdata.size
-  end
-  if not parameters.extendfactor then
-    parameters.extendfactor=tfmdata.extend or 0
-  end
-  if not parameters.slantfactor then
-    parameters.slantfactor=tfmdata.slant or 0
-  end
-  local designsize=parameters.designsize
-  if designsize then
-    parameters.minsize=tfmdata.minsize or designsize
-    parameters.maxsize=tfmdata.maxsize or designsize
-  else
-    designsize=factors.pt*10
-    parameters.designsize=designsize
-    parameters.minsize=designsize
-    parameters.maxsize=designsize
-  end
-  parameters.minsize=tfmdata.minsize or parameters.designsize
-  parameters.maxsize=tfmdata.maxsize or parameters.designsize
-  if not parameters.units then
-    parameters.units=tfmdata.units or tfmdata.units_per_em or 1000
-  end
-  if not tfmdata.descriptions then
-    local descriptions={} 
-    setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end)
-    tfmdata.descriptions=descriptions
-  end
-  local properties=tfmdata.properties
-  if not properties then
-    properties={}
-    tfmdata.properties=properties
-  end
-  if not properties.virtualized then
-    properties.virtualized=tfmdata.type=="virtual"
-  end
-  if not tfmdata.properties then
-    tfmdata.properties={
-      fontname=tfmdata.fontname,
-      filename=tfmdata.filename,
-      fullname=tfmdata.fullname,
-      name=tfmdata.name,
-      psname=tfmdata.psname,
-      encodingbytes=tfmdata.encodingbytes or 1,
-      embedding=tfmdata.embedding   or "subset",
-      tounicode=tfmdata.tounicode   or 1,
-      cidinfo=tfmdata.cidinfo    or nil,
-      format=tfmdata.format    or "type1",
-      direction=tfmdata.direction   or 0,
-      writingmode=tfmdata.writingmode  or "horizontal",
-      identity=tfmdata.identity   or "horizontal",
-    }
-  end
-  if not tfmdata.resources then
-    tfmdata.resources={}
-  end
-  if not tfmdata.shared then
-    tfmdata.shared={}
-  end
-  if not properties.hasmath then
-    properties.hasmath=not tfmdata.nomath
-  end
-  tfmdata.MathConstants=nil
-  tfmdata.postprocessors=nil
-  tfmdata.fontname=nil
-  tfmdata.filename=nil
-  tfmdata.fullname=nil
-  tfmdata.name=nil 
-  tfmdata.psname=nil
-  tfmdata.encodingbytes=nil
-  tfmdata.embedding=nil
-  tfmdata.tounicode=nil
-  tfmdata.cidinfo=nil
-  tfmdata.format=nil
-  tfmdata.direction=nil
-  tfmdata.type=nil
-  tfmdata.nomath=nil
-  tfmdata.designsize=nil
-  tfmdata.size=nil
-  tfmdata.stretch=nil
-  tfmdata.shrink=nil
-  tfmdata.step=nil
-  tfmdata.auto_expand=nil
-  tfmdata.auto_protrude=nil
-  tfmdata.extend=nil
-  tfmdata.slant=nil
-  tfmdata.units=nil
-  tfmdata.units_per_em=nil
-  tfmdata.cache=nil
-  properties.finalized=true
-  return tfmdata
-end
-local hashmethods={}
-constructors.hashmethods=hashmethods
-function constructors.hashfeatures(specification) 
-  local features=specification.features
-  if features then
-    local t,tn={},0
-    for category,list in next,features do
-      if next(list) then
-        local hasher=hashmethods[category]
-        if hasher then
-          local hash=hasher(list)
-          if hash then
-            tn=tn+1
-            t[tn]=category..":"..hash
-          end
-        end
-      end
-    end
-    if tn>0 then
-      return concat(t," & ")
-    end
-  end
-  return "unknown"
-end
-hashmethods.normal=function(list)
-  local s={}
-  local n=0
-  for k,v in next,list do
-    if not k then
-    elseif k=="number" or k=="features" then
-    else
-      n=n+1
-      s[n]=k..'='..tostring(v)
-    end
-  end
-  if n>0 then
-    sort(s)
-    return concat(s,"+")
-  end
-end
-function constructors.hashinstance(specification,force)
-  local hash,size,fallbacks=specification.hash,specification.size,specification.fallbacks
-  if force or not hash then
-    hash=constructors.hashfeatures(specification)
-    specification.hash=hash
-  end
-  if size<1000 and designsizes[hash] then
-    size=math.round(constructors.scaled(size,designsizes[hash]))
-    specification.size=size
-  end
-  if fallbacks then
-    return hash..' @ '..tostring(size)..' @ '..fallbacks
-  else
-    return hash..' @ '..tostring(size)
-  end
-end
-function constructors.setname(tfmdata,specification) 
-  if constructors.namemode=="specification" then
-    local specname=specification.specification
-    if specname then
-      tfmdata.properties.name=specname
-      if trace_defining then
-        report_otf("overloaded fontname %a",specname)
-      end
-    end
-  end
-end
-function constructors.checkedfilename(data)
-  local foundfilename=data.foundfilename
-  if not foundfilename then
-    local askedfilename=data.filename or ""
-    if askedfilename~="" then
-      askedfilename=resolvers.resolve(askedfilename) 
-      foundfilename=resolvers.findbinfile(askedfilename,"") or ""
-      if foundfilename=="" then
-        report_defining("source file %a is not found",askedfilename)
-        foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or ""
-        if foundfilename~="" then
-          report_defining("using source file %a due to cache mismatch",foundfilename)
-        end
-      end
-    end
-    data.foundfilename=foundfilename
-  end
-  return foundfilename
-end
-local formats=allocate()
-fonts.formats=formats
-setmetatableindex(formats,function(t,k)
-  local l=lower(k)
-  if rawget(t,k) then
-    t[k]=l
-    return l
-  end
-  return rawget(t,file.suffix(l))
-end)
-do
-  local function setindeed(mode,source,target,group,name,position)
-    local action=source[mode]
-    if not action then
-      return
-    end
-    local t=target[mode]
-    if not t then
-      report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode)
-      os.exit()
-    elseif position then
-      insert(t,position,{ name=name,action=action })
-    else
-      for i=1,#t do
-        local ti=t[i]
-        if ti.name==name then
-          ti.action=action
-          return
-        end
-      end
-      insert(t,{ name=name,action=action })
-    end
-  end
-  local function set(group,name,target,source)
-    target=target[group]
-    if not target then
-      report_defining("fatal target error in setting feature %a, group %a",name,group)
-      os.exit()
-    end
-    local source=source[group]
-    if not source then
-      report_defining("fatal source error in setting feature %a, group %a",name,group)
-      os.exit()
-    end
-    local position=source.position
-    setindeed("node",source,target,group,name,position)
-    setindeed("base",source,target,group,name,position)
-    setindeed("plug",source,target,group,name,position)
-  end
-  local function register(where,specification)
-    local name=specification.name
-    if name and name~="" then
-      local default=specification.default
-      local description=specification.description
-      local initializers=specification.initializers
-      local processors=specification.processors
-      local manipulators=specification.manipulators
-      local modechecker=specification.modechecker
-      if default then
-        where.defaults[name]=default
-      end
-      if description and description~="" then
-        where.descriptions[name]=description
-      end
-      if initializers then
-        set('initializers',name,where,specification)
-      end
-      if processors then
-        set('processors',name,where,specification)
-      end
-      if manipulators then
-        set('manipulators',name,where,specification)
-      end
-      if modechecker then
-        where.modechecker=modechecker
-      end
-    end
-  end
-  constructors.registerfeature=register
-  function constructors.getfeatureaction(what,where,mode,name)
-    what=handlers[what].features
-    if what then
-      where=what[where]
-      if where then
-        mode=where[mode]
-        if mode then
-          for i=1,#mode do
-            local m=mode[i]
-            if m.name==name then
-              return m.action
-            end
-          end
-        end
-      end
-    end
-  end
-  local newfeatures={}
-  constructors.newfeatures=newfeatures 
-  constructors.features=newfeatures
-  local function setnewfeatures(what)
-    local handler=handlers[what]
-    local features=handler.features
-    if not features then
-      local tables=handler.tables   
-      local statistics=handler.statistics 
-      features=allocate {
-        defaults={},
-        descriptions=tables and tables.features or {},
-        used=statistics and statistics.usedfeatures or {},
-        initializers={ base={},node={},plug={} },
-        processors={ base={},node={},plug={} },
-        manipulators={ base={},node={},plug={} },
-      }
-      features.register=function(specification) return register(features,specification) end
-      handler.features=features 
-    end
-    return features
-  end
-  setmetatable(newfeatures,{
-    __call=function(t,k) local v=t[k] return v end,
-    __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end,
-  })
-end
-do
-  local newhandler={}
-  constructors.handlers=newhandler 
-  constructors.newhandler=newhandler
-  local function setnewhandler(what) 
-    local handler=handlers[what]
-    if not handler then
-      handler={}
-      handlers[what]=handler
-    end
-    return handler
-  end
-  setmetatable(newhandler,{
-    __call=function(t,k) local v=t[k] return v end,
-    __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end,
-  })
-end
-do
-  local newenhancer={}
-  constructors.enhancers=newenhancer
-  constructors.newenhancer=newenhancer
-  local function setnewenhancer(format)
-    local handler=handlers[format]
-    local enhancers=handler.enhancers
-    if not enhancers then
-      local actions=allocate()
-      local before=allocate()
-      local after=allocate()
-      local order=allocate()
-      local patches={ before=before,after=after }
-      local trace=false
-      local report=logs.reporter("fonts",format.." enhancing")
-      trackers.register(format..".loading",function(v) trace=v end)
-      local function enhance(name,data,filename,raw)
-        local enhancer=actions[name]
-        if enhancer then
-          if trace then
-            report("apply enhancement %a to file %a",name,filename)
-            ioflush()
-          end
-          enhancer(data,filename,raw)
-        else
-        end
-      end
-      local function apply(data,filename,raw)
-        local basename=file.basename(lower(filename))
-        if trace then
-          report("%s enhancing file %a","start",filename)
-        end
-        ioflush() 
-        for e=1,#order do
-          local enhancer=order[e]
-          local b=before[enhancer]
-          if b then
-            for pattern,action in next,b do
-              if find(basename,pattern) then
-                action(data,filename,raw)
-              end
-            end
-          end
-          enhance(enhancer,data,filename,raw)
-          local a=after[enhancer]
-          if a then
-            for pattern,action in next,a do
-              if find(basename,pattern) then
-                action(data,filename,raw)
-              end
-            end
-          end
-          ioflush() 
-        end
-        if trace then
-          report("%s enhancing file %a","stop",filename)
-        end
-        ioflush() 
-      end
-      local function register(what,action)
-        if action then
-          if actions[what] then
-          else
-            order[#order+1]=what
-          end
-          actions[what]=action
-        else
-          report("bad enhancer %a",what)
-        end
-      end
-      local function patch(what,where,pattern,action)
-        local pw=patches[what]
-        if pw then
-          local ww=pw[where]
-          if ww then
-            ww[pattern]=action
-          else
-            pw[where]={ [pattern]=action}
-          end
-        end
-      end
-      enhancers={
-        register=register,
-        apply=apply,
-        patch=patch,
-        patches={ register=patch },
-      }
-      handler.enhancers=enhancers
-    end
-    return enhancers
-  end
-  setmetatable(newenhancer,{
-    __call=function(t,k) local v=t[k] return v end,
-    __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end,
-  })
-end
-function constructors.checkedfeatures(what,features)
-  local defaults=handlers[what].features.defaults
-  if features and next(features) then
-    features=fastcopy(features) 
-    for key,value in next,defaults do
-      if features[key]==nil then
-        features[key]=value
-      end
-    end
-    return features
-  else
-    return fastcopy(defaults) 
-  end
-end
-function constructors.initializefeatures(what,tfmdata,features,trace,report)
-  if features and next(features) then
-    local properties=tfmdata.properties or {} 
-    local whathandler=handlers[what]
-    local whatfeatures=whathandler.features
-    local whatmodechecker=whatfeatures.modechecker
-    local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base"
-    properties.mode=mode 
-    features.mode=mode
-    local done={}
-    while true do
-      local redo=false
-      local initializers=whatfeatures.initializers[mode]
-      if initializers then
-        for i=1,#initializers do
-          local step=initializers[i]
-          local feature=step.name
-          local value=features[feature]
-          if not value then
-          elseif done[feature] then
-          else
-            local action=step.action
-            if trace then
-              report("initializing feature %a to %a for mode %a for font %a",feature,
-                value,mode,tfmdata.properties.fullname)
-            end
-            action(tfmdata,value,features) 
-            if mode~=properties.mode or mode~=features.mode then
-              if whatmodechecker then
-                properties.mode=whatmodechecker(tfmdata,features,properties.mode) 
-                features.mode=properties.mode
-              end
-              if mode~=properties.mode then
-                mode=properties.mode
-                redo=true
-              end
-            end
-            done[feature]=true
-          end
-          if redo then
-            break
-          end
-        end
-        if not redo then
-          break
-        end
-      else
-        break
-      end
-    end
-    properties.mode=mode 
-    return true
-  else
-    return false
-  end
-end
-function constructors.collectprocessors(what,tfmdata,features,trace,report)
-  local processes,nofprocesses={},0
-  if features and next(features) then
-    local properties=tfmdata.properties
-    local whathandler=handlers[what]
-    local whatfeatures=whathandler.features
-    local whatprocessors=whatfeatures.processors
-    local mode=properties.mode
-    local processors=whatprocessors[mode]
-    if processors then
-      for i=1,#processors do
-        local step=processors[i]
-        local feature=step.name
-        if features[feature] then
-          local action=step.action
-          if trace then
-            report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname)
-          end
-          if action then
-            nofprocesses=nofprocesses+1
-            processes[nofprocesses]=action
-          end
-        end
-      end
-    elseif trace then
-      report("no feature processors for mode %a for font %a",mode,properties.fullname)
-    end
-  end
-  return processes
-end
-function constructors.applymanipulators(what,tfmdata,features,trace,report)
-  if features and next(features) then
-    local properties=tfmdata.properties
-    local whathandler=handlers[what]
-    local whatfeatures=whathandler.features
-    local whatmanipulators=whatfeatures.manipulators
-    local mode=properties.mode
-    local manipulators=whatmanipulators[mode]
-    if manipulators then
-      for i=1,#manipulators do
-        local step=manipulators[i]
-        local feature=step.name
-        local value=features[feature]
-        if value then
-          local action=step.action
-          if trace then
-            report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname)
-          end
-          if action then
-            action(tfmdata,feature,value)
-          end
-        end
-      end
-    end
-  end
-end
-function constructors.addcoreunicodes(unicodes) 
-  if not unicodes then
-    unicodes={}
-  end
-  unicodes.space=0x0020
-  unicodes.hyphen=0x002D
-  unicodes.zwj=0x200D
-  unicodes.zwnj=0x200C
-  return unicodes
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-con”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “fonts-enc” a7ace7c1969cd64a5ca9888838f3edb6] ---
-
-if not modules then modules={} end modules ['luatex-font-enc']={
-  version=1.001,
-  comment="companion to luatex-*.tex",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-if context then
-  texio.write_nl("fatal error: this module is not for context")
-  os.exit()
-end
-local fonts=fonts
-local encodings={}
-fonts.encodings=encodings
-encodings.agl={}
-encodings.known={}
-setmetatable(encodings.agl,{ __index=function(t,k)
-  if k=="unicodes" then
-    texio.write(" <loading (extended) adobe glyph list>")
-    local unicodes=dofile(resolvers.findfile("font-age.lua"))
-    encodings.agl={ unicodes=unicodes }
-    return unicodes
-  else
-    return nil
-  end
-end })
-encodings.cache=containers.define("fonts","enc",encodings.version,true)
-function encodings.load(filename)
-  local name=file.removesuffix(filename)
-  local data=containers.read(encodings.cache,name)
-  if data then
-    return data
-  end
-  local vector,tag,hash,unicodes={},"",{},{}
-  local foundname=resolvers.findfile(filename,'enc')
-  if foundname and foundname~="" then
-    local ok,encoding,size=resolvers.loadbinfile(foundname)
-    if ok and encoding then
-      encoding=string.gsub(encoding,"%%(.-)\n","")
-      local unicoding=encodings.agl.unicodes
-      local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def")
-      local i=0
-      for ch in string.gmatch(vec,"/([%a%d%.]+)") do
-        if ch~=".notdef" then
-          vector[i]=ch
-          if not hash[ch] then
-            hash[ch]=i
-          else
-          end
-          local u=unicoding[ch]
-          if u then
-            unicodes[u]=i
-          end
-        end
-        i=i+1
-      end
-    end
-  end
-  local data={
-    name=name,
-    tag=tag,
-    vector=vector,
-    hash=hash,
-    unicodes=unicodes
-  }
-  return containers.write(encodings.cache,name,data)
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “fonts-enc”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-cid” 52421d1fdaa07ec4b1d936c6ff5079be] ---
-
-if not modules then modules={} end modules ['font-cid']={
-  version=1.001,
-  comment="companion to font-otf.lua (cidmaps)",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local format,match,lower=string.format,string.match,string.lower
-local tonumber=tonumber
-local P,S,R,C,V,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.match
-local fonts,logs,trackers=fonts,logs,trackers
-local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
-local report_otf=logs.reporter("fonts","otf loading")
-local cid={}
-fonts.cid=cid
-local cidmap={}
-local cidmax=10
-local number=C(R("09","af","AF")^1)
-local space=S(" \n\r\t")
-local spaces=space^0
-local period=P(".")
-local periods=period*period
-local name=P("/")*C((1-space)^1)
-local unicodes,names={},{} 
-local function do_one(a,b)
-  unicodes[tonumber(a)]=tonumber(b,16)
-end
-local function do_range(a,b,c)
-  c=tonumber(c,16)
-  for i=tonumber(a),tonumber(b) do
-    unicodes[i]=c
-    c=c+1
-  end
-end
-local function do_name(a,b)
-  names[tonumber(a)]=b
-end
-local grammar=P { "start",
-  start=number*spaces*number*V("series"),
-  series=(spaces*(V("one")+V("range")+V("named")))^1,
-  one=(number*spaces*number)/do_one,
-  range=(number*periods*number*spaces*number)/do_range,
-  named=(number*spaces*name)/do_name
-}
-local function loadcidfile(filename)
-  local data=io.loaddata(filename)
-  if data then
-    unicodes,names={},{}
-    lpegmatch(grammar,data)
-    local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$")
-    return {
-      supplement=supplement,
-      registry=registry,
-      ordering=ordering,
-      filename=filename,
-      unicodes=unicodes,
-      names=names,
-    }
-  end
-end
-cid.loadfile=loadcidfile 
-local template="%s-%s-%s.cidmap"
-local function locate(registry,ordering,supplement)
-  local filename=format(template,registry,ordering,supplement)
-  local hashname=lower(filename)
-  local found=cidmap[hashname]
-  if not found then
-    if trace_loading then
-      report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename)
-    end
-    local fullname=resolvers.findfile(filename,'cid') or ""
-    if fullname~="" then
-      found=loadcidfile(fullname)
-      if found then
-        if trace_loading then
-          report_otf("using cidmap file %a",filename)
-        end
-        cidmap[hashname]=found
-        found.usedname=file.basename(filename)
-      end
-    end
-  end
-  return found
-end
-function cid.getmap(specification)
-  if not specification then
-    report_otf("invalid cidinfo specification, table expected")
-    return
-  end
-  local registry=specification.registry
-  local ordering=specification.ordering
-  local supplement=specification.supplement
-  local filename=format(registry,ordering,supplement)
-  local lowername=lower(filename)
-  local found=cidmap[lowername]
-  if found then
-    return found
-  end
-  if ordering=="Identity" then
-    local found={
-      supplement=supplement,
-      registry=registry,
-      ordering=ordering,
-      filename=filename,
-      unicodes={},
-      names={},
-    }
-    cidmap[lowername]=found
-    return found
-  end
-  if trace_loading then
-    report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement)
-  end
-  found=locate(registry,ordering,supplement)
-  if not found then
-    local supnum=tonumber(supplement)
-    local cidnum=nil
-    if supnum<cidmax then
-      for s=supnum+1,cidmax do
-        local c=locate(registry,ordering,s)
-        if c then
-          found,cidnum=c,s
-          break
-        end
-      end
-    end
-    if not found and supnum>0 then
-      for s=supnum-1,0,-1 do
-        local c=locate(registry,ordering,s)
-        if c then
-          found,cidnum=c,s
-          break
-        end
-      end
-    end
-    registry=lower(registry)
-    ordering=lower(ordering)
-    if found and cidnum>0 then
-      for s=0,cidnum-1 do
-        local filename=format(template,registry,ordering,s)
-        if not cidmap[filename] then
-          cidmap[filename]=found
-        end
-      end
-    end
-  end
-  return found
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-cid”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-map” 8708bde7467785c4d3b7afdaf2f9333a] ---
-
-if not modules then modules={} end modules ['font-map']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local tonumber,next,type=tonumber,next,type
-local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower
-local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match
-local floor=math.floor
-local formatters=string.formatters
-local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
-local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end)
-local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end)
-local report_fonts=logs.reporter("fonts","loading") 
-local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end)
-local fonts=fonts or {}
-local mappings=fonts.mappings or {}
-fonts.mappings=mappings
-local allocate=utilities.storage.allocate
-local hex=R("AF","af","09")
-local hexfour=(hex*hex*hex^-2)/function(s) return tonumber(s,16) end
-local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end
-local dec=(R("09")^1)/tonumber
-local period=P(".")
-local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true)) 
-local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true)) 
-local index=P("index")*dec*Cc(false)
-local parser=unicode+ucode+index
-local parsers={}
-local function makenameparser(str)
-  if not str or str=="" then
-    return parser
-  else
-    local p=parsers[str]
-    if not p then
-      p=P(str)*period*dec*Cc(false)
-      parsers[str]=p
-    end
-    return p
-  end
-end
-local f_single=formatters["%04X"]
-local f_double=formatters["%04X%04X"]
-local function tounicode16(unicode)
-  if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then
-    return f_single(unicode)
-  else
-    unicode=unicode-0x10000
-    return f_double(floor(unicode/1024)+0xD800,unicode%1024+0xDC00)
-  end
-end
-local function tounicode16sequence(unicodes)
-  local t={}
-  for l=1,#unicodes do
-    local u=unicodes[l]
-    if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then
-      t[l]=f_single(u)
-    else
-      u=u-0x10000
-      t[l]=f_double(floor(u/1024)+0xD800,u%1024+0xDC00)
-    end
-  end
-  return concat(t)
-end
-local function tounicode(unicode,name)
-  if type(unicode)=="table" then
-    local t={}
-    for l=1,#unicode do
-      local u=unicode[l]
-      if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then
-        t[l]=f_single(u)
-      else
-        u=u-0x10000
-        t[l]=f_double(floor(u/1024)+0xD800,u%1024+0xDC00)
-      end
-    end
-    return concat(t)
-  else
-    if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then
-      return f_single(unicode)
-    else
-      unicode=unicode-0x10000
-      return f_double(floor(unicode/1024)+0xD800,unicode%1024+0xDC00)
-    end
-  end
-end
-local function fromunicode16(str)
-  if #str==4 then
-    return tonumber(str,16)
-  else
-    local l,r=match(str,"(....)(....)")
-    return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00
-  end
-end
-mappings.makenameparser=makenameparser
-mappings.tounicode=tounicode
-mappings.tounicode16=tounicode16
-mappings.tounicode16sequence=tounicode16sequence
-mappings.fromunicode16=fromunicode16
-local ligseparator=P("_")
-local varseparator=P(".")
-local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0)
-do
-  local overloads=allocate {
-    IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 },
-    ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 },
-    ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 },
-    fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 },
-    fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 },
-    ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 },
-    ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 },
-    fj={ name="f_j",unicode={ 0x66,0x6A } },
-    fk={ name="f_k",unicode={ 0x66,0x6B } },
-  }
-  local o={}
-  for k,v in next,overloads do
-    local name=v.name
-    local mess=v.mess
-    if name then
-      o[name]=v
-    end
-    if mess then
-      o[mess]=v
-    end
-    o[k]=v
-  end
-  mappings.overloads=o
-end
-function mappings.addtounicode(data,filename,checklookups)
-  local resources=data.resources
-  local unicodes=resources.unicodes
-  if not unicodes then
-    if trace_mapping then
-      report_fonts("no unicode list, quitting tounicode for %a",filename)
-    end
-    return
-  end
-  local properties=data.properties
-  local descriptions=data.descriptions
-  local overloads=mappings.overloads
-  unicodes['space']=unicodes['space'] or 32
-  unicodes['hyphen']=unicodes['hyphen'] or 45
-  unicodes['zwj']=unicodes['zwj']  or 0x200D
-  unicodes['zwnj']=unicodes['zwnj']  or 0x200C
-  local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 
-  local unicodevector=fonts.encodings.agl.unicodes or {} 
-  local contextvector=fonts.encodings.agl.ctxcodes or {} 
-  local missing={}
-  local nofmissing=0
-  local oparser=nil
-  local cidnames=nil
-  local cidcodes=nil
-  local cidinfo=properties.cidinfo
-  local usedmap=cidinfo and fonts.cid.getmap(cidinfo)
-  local uparser=makenameparser() 
-  if usedmap then
-     oparser=usedmap and makenameparser(cidinfo.ordering)
-     cidnames=usedmap.names
-     cidcodes=usedmap.unicodes
-  end
-  local ns=0
-  local nl=0
-  local dlist=sortedkeys(descriptions)
-  for i=1,#dlist do
-    local du=dlist[i]
-    local glyph=descriptions[du]
-    local name=glyph.name
-    if name then
-      local overload=overloads[name] or overloads[du]
-      if overload then
-        glyph.unicode=overload.unicode
-      else
-        local gu=glyph.unicode 
-        if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then
-          local unicode=unicodevector[name] or contextvector[name]
-          if unicode then
-            glyph.unicode=unicode
-            ns=ns+1
-          end
-          if (not unicode) and usedmap then
-            local foundindex=lpegmatch(oparser,name)
-            if foundindex then
-              unicode=cidcodes[foundindex] 
-              if unicode then
-                glyph.unicode=unicode
-                ns=ns+1
-              else
-                local reference=cidnames[foundindex] 
-                if reference then
-                  local foundindex=lpegmatch(oparser,reference)
-                  if foundindex then
-                    unicode=cidcodes[foundindex]
-                    if unicode then
-                      glyph.unicode=unicode
-                      ns=ns+1
-                    end
-                  end
-                  if not unicode or unicode=="" then
-                    local foundcodes,multiple=lpegmatch(uparser,reference)
-                    if foundcodes then
-                      glyph.unicode=foundcodes
-                      if multiple then
-                        nl=nl+1
-                        unicode=true
-                      else
-                        ns=ns+1
-                        unicode=foundcodes
-                      end
-                    end
-                  end
-                end
-              end
-            end
-          end
-          if not unicode or unicode=="" then
-            local split=lpegmatch(namesplitter,name)
-            local nsplit=split and #split or 0 
-            if nsplit==0 then
-            elseif nsplit==1 then
-              local base=split[1]
-              local u=unicodes[base] or unicodevector[base] or contextvector[name]
-              if not u then
-              elseif type(u)=="table" then
-                if u[1]<private then
-                  unicode=u
-                  glyph.unicode=unicode
-                end
-              elseif u<private then
-                unicode=u
-                glyph.unicode=unicode
-              end
-            else
-              local t,n={},0
-              for l=1,nsplit do
-                local base=split[l]
-                local u=unicodes[base] or unicodevector[base] or contextvector[name]
-                if not u then
-                  break
-                elseif type(u)=="table" then
-                  if u[1]>=private then
-                    break
-                  end
-                  n=n+1
-                  t[n]=u[1]
-                else
-                  if u>=private then
-                    break
-                  end
-                  n=n+1
-                  t[n]=u
-                end
-              end
-              if n>0 then
-                if n==1 then
-                  unicode=t[1]
-                else
-                  unicode=t
-                end
-                glyph.unicode=unicode
-              end
-            end
-            nl=nl+1
-          end
-          if not unicode or unicode=="" then
-            local foundcodes,multiple=lpegmatch(uparser,name)
-            if foundcodes then
-              glyph.unicode=foundcodes
-              if multiple then
-                nl=nl+1
-                unicode=true
-              else
-                ns=ns+1
-                unicode=foundcodes
-              end
-            end
-          end
-          local r=overloads[unicode]
-          if r then
-            unicode=r.unicode
-            glyph.unicode=unicode
-          end
-          if not unicode then
-            missing[du]=true
-            nofmissing=nofmissing+1
-          end
-        end
-      end
-    else
-      local overload=overloads[du]
-      if overload then
-        glyph.unicode=overload.unicode
-      end
-    end
-  end
-  if type(checklookups)=="function" then
-    checklookups(data,missing,nofmissing)
-  end
-  local collected=false
-  local unicoded=0
-  for i=1,#dlist do
-    local du=dlist[i]
-    local glyph=descriptions[du]
-    if glyph.class=="ligature" and (force_ligatures or not glyph.unicode) then
-      if not collected then
-        collected=fonts.handlers.otf.readers.getcomponents(data)
-        if not collected then
-          break
-        end
-      end
-      local u=collected[du] 
-      if u then
-        local n=#u
-        for i=1,n do
-          if u[i]>private then
-            n=0
-            break
-          end
-        end
-        if n>0 then
-          if n>1 then
-            glyph.unicode=u
-          else
-            glyph.unicode=u[1]
-          end
-          unicoded=unicoded+1
-        end
-      end
-    end
-  end
-  if trace_mapping and unicoded>0 then
-    report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded)
-  end
-  if trace_mapping then
-    for i=1,#dlist do
-      local du=dlist[i]
-      local glyph=descriptions[du]
-      local name=glyph.name or "-"
-      local index=glyph.index or 0
-      local unicode=glyph.unicode
-      if unicode then
-        if type(unicode)=="table" then
-          local unicodes={}
-          for i=1,#unicode do
-            unicodes[i]=formatters("%U",unicode[i])
-          end
-          report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes)
-        else
-          report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode)
-        end
-      else
-        report_fonts("internal slot %U, name %a, unicode %U",index,name,du)
-      end
-    end
-  end
-  if trace_loading and (ns>0 or nl>0) then
-    report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns)
-  end
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-map”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-oti” 8f48c06a1d632febd7231ad5dfadfc53] ---
-
-if not modules then modules={} end modules ['font-oti']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local lower=string.lower
-local fonts=fonts
-local constructors=fonts.constructors
-local otf=constructors.handlers.otf
-local otffeatures=constructors.features.otf
-local registerotffeature=otffeatures.register
-local otftables=otf.tables or {}
-otf.tables=otftables
-local allocate=utilities.storage.allocate
-registerotffeature {
-  name="features",
-  description="initialization of feature handler",
-  default=true,
-}
-local function setmode(tfmdata,value)
-  if value then
-    tfmdata.properties.mode=lower(value)
-  end
-end
-otf.modeinitializer=setmode
-local function setlanguage(tfmdata,value)
-  if value then
-    local cleanvalue=lower(value)
-    local languages=otftables and otftables.languages
-    local properties=tfmdata.properties
-    if not languages then
-      properties.language=cleanvalue
-    elseif languages[value] then
-      properties.language=cleanvalue
-    else
-      properties.language="dflt"
-    end
-  end
-end
-local function setscript(tfmdata,value)
-  if value then
-    local cleanvalue=lower(value)
-    local scripts=otftables and otftables.scripts
-    local properties=tfmdata.properties
-    if not scripts then
-      properties.script=cleanvalue
-    elseif scripts[value] then
-      properties.script=cleanvalue
-    else
-      properties.script="dflt"
-    end
-  end
-end
-registerotffeature {
-  name="mode",
-  description="mode",
-  initializers={
-    base=setmode,
-    node=setmode,
-    plug=setmode,
-  }
-}
-registerotffeature {
-  name="language",
-  description="language",
-  initializers={
-    base=setlanguage,
-    node=setlanguage,
-    plug=setlanguage,
-  }
-}
-registerotffeature {
-  name="script",
-  description="script",
-  initializers={
-    base=setscript,
-    node=setscript,
-    plug=setscript,
-  }
-}
-otftables.featuretypes=allocate {
-  gpos_single="position",
-  gpos_pair="position",
-  gpos_cursive="position",
-  gpos_mark2base="position",
-  gpos_mark2ligature="position",
-  gpos_mark2mark="position",
-  gpos_context="position",
-  gpos_contextchain="position",
-  gsub_single="substitution",
-  gsub_multiple="substitution",
-  gsub_alternate="substitution",
-  gsub_ligature="substitution",
-  gsub_context="substitution",
-  gsub_contextchain="substitution",
-  gsub_reversecontextchain="substitution",
-  gsub_reversesub="substitution",
-}
-function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts)
-  if featuretype=="position" then
-    local default=scripts.dflt
-    if default then
-      if autoscript=="position" or autoscript==true then
-        return default
-      else
-        report_otf("script feature %s not applied, enable default positioning")
-      end
-    else
-    end
-  elseif featuretype=="substitution" then
-    local default=scripts.dflt
-    if default then
-      if autoscript=="substitution" or autoscript==true then
-        return default
-      end
-    end
-  end
-end
-function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
-  if featuretype=="position" then
-    local default=languages.dflt
-    if default then
-      if autolanguage=="position" or autolanguage==true then
-        return default
-      else
-        report_otf("language feature %s not applied, enable default positioning")
-      end
-    else
-    end
-  elseif featuretype=="substitution" then
-    local default=languages.dflt
-    if default then
-      if autolanguage=="substitution" or autolanguage==true then
-        return default
-      end
-    end
-  end
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-oti”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-otr” 2bd0085b78027f261218d63034f43474] ---
-
-if not modules then modules={} end modules ['font-otr']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local next,type,unpack=next,type,unpack
-local byte,lower,char,strip,gsub=string.byte,string.lower,string.char,string.strip,string.gsub
-local bittest=bit32.btest
-local concat,remove,unpack,fastcopy=table.concat,table.remov,table.unpack,table.fastcopy
-local floor,abs,sqrt,round=math.floor,math.abs,math.sqrt,math.round
-local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt
-local lpegmatch=lpeg.match
-local setmetatableindex=table.setmetatableindex
-local formatters=string.formatters
-local sortedkeys=table.sortedkeys
-local sortedhash=table.sortedhash
-local stripstring=string.strip
-local utf16_to_utf8_be=utf.utf16_to_utf8_be
-local report=logs.reporter("otf reader")
-local trace_cmap=false 
-fonts=fonts or {}
-local handlers=fonts.handlers or {}
-fonts.handlers=handlers
-local otf=handlers.otf or {}
-handlers.otf=otf
-local readers=otf.readers or {}
-otf.readers=readers
-local streamreader=utilities.files  
-local streamwriter=utilities.files
-readers.streamreader=streamreader
-readers.streamwriter=streamwriter
-local openfile=streamreader.open
-local closefile=streamreader.close
-local setposition=streamreader.setposition
-local skipshort=streamreader.skipshort
-local readbytes=streamreader.readbytes
-local readstring=streamreader.readstring
-local readbyte=streamreader.readcardinal1 
-local readushort=streamreader.readcardinal2 
-local readuint=streamreader.readcardinal3 
-local readulong=streamreader.readcardinal4
-local readshort=streamreader.readinteger2  
-local readlong=streamreader.readinteger4  
-local readfixed=streamreader.readfixed4
-local readfword=readshort          
-local readufword=readushort         
-local readoffset=readushort
-local read2dot14=streamreader.read2dot14   
-function streamreader.readtag(f)
-  return lower(strip(readstring(f,4)))
-end
-local function readlongdatetime(f)
-  local a,b,c,d,e,f,g,h=readbytes(f,8)
-  return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
-end
-local tableversion=0.004
-readers.tableversion=tableversion
-local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 
-local reportedskipped={}
-local function reportskippedtable(tag)
-  if not reportedskipped[tag] then
-    report("loading of table %a skipped (reported once only)",tag)
-    reportedskipped[tag]=true
-  end
-end
-local reservednames={ [0]="copyright",
-  "family",
-  "subfamily",
-  "uniqueid",
-  "fullname",
-  "version",
-  "postscriptname",
-  "trademark",
-  "manufacturer",
-  "designer",
-  "description",
-  "vendorurl",
-  "designerurl",
-  "license",
-  "licenseurl",
-  "reserved",
-  "typographicfamily",
-  "typographicsubfamily",
-  "compatiblefullname",
-  "sampletext",
-  "cidfindfontname",
-  "wwsfamily",
-  "wwssubfamily",
-  "lightbackgroundpalette",
-  "darkbackgroundpalette",
-}
-local platforms={ [0]="unicode",
-  "macintosh",
-  "iso",
-  "windows",
-  "custom",
-}
-local encodings={
-  unicode={ [0]="unicode 1.0 semantics",
-    "unicode 1.1 semantics",
-    "iso/iec 10646",
-    "unicode 2.0 bmp",
-    "unicode 2.0 full",
-    "unicode variation sequences",
-    "unicode full repertoire",
-  },
-  macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian",
-    "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada",
-    "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian",
-    "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi",
-    "uninterpreted",
-  },
-  iso={ [0]="7-bit ascii",
-    "iso 10646",
-    "iso 8859-1",
-  },
-  windows={ [0]="symbol",
-    "unicode bmp",
-    "shiftjis",
-    "prc",
-    "big5",
-    "wansung",
-    "johab",
-    "reserved 7",
-    "reserved 8",
-    "reserved 9",
-    "unicode ucs-4",
-  },
-  custom={
-  }
-}
-local decoders={
-  unicode={},
-  macintosh={},
-  iso={},
-  windows={
-    ["unicode semantics"]=utf16_to_utf8_be,
-    ["unicode bmp"]=utf16_to_utf8_be,
-    ["unicode full"]=utf16_to_utf8_be,
-    ["unicode 1.0 semantics"]=utf16_to_utf8_be,
-    ["unicode 1.1 semantics"]=utf16_to_utf8_be,
-    ["unicode 2.0 bmp"]=utf16_to_utf8_be,
-    ["unicode 2.0 full"]=utf16_to_utf8_be,
-    ["unicode variation sequences"]=utf16_to_utf8_be,
-    ["unicode full repertoire"]=utf16_to_utf8_be,
-  },
-  custom={},
-}
-local languages={
-  unicode={
-    [ 0]="english",
-  },
-  macintosh={
-    [ 0]="english",
-  },
-  iso={},
-  windows={
-    [0x0409]="english - united states",
-  },
-  custom={},
-}
-local standardromanencoding={ [0]=
-  "notdef",".null","nonmarkingreturn","space","exclam","quotedbl",
-  "numbersign","dollar","percent","ampersand","quotesingle","parenleft",
-  "parenright","asterisk","plus","comma","hyphen","period","slash",
-  "zero","one","two","three","four","five","six","seven","eight",
-  "nine","colon","semicolon","less","equal","greater","question","at",
-  "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O",
-  "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft",
-  "backslash","bracketright","asciicircum","underscore","grave","a","b",
-  "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q",
-  "r","s","t","u","v","w","x","y","z","braceleft","bar",
-  "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute",
-  "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex",
-  "adieresis","atilde","aring","ccedilla","eacute","egrave",
-  "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis",
-  "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute",
-  "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling",
-  "section","bullet","paragraph","germandbls","registered","copyright",
-  "trademark","acute","dieresis","notequal","AE","Oslash","infinity",
-  "plusminus","lessequal","greaterequal","yen","mu","partialdiff",
-  "summation","product","pi","integral","ordfeminine","ordmasculine",
-  "Omega","ae","oslash","questiondown","exclamdown","logicalnot",
-  "radical","florin","approxequal","Delta","guillemotleft",
-  "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde",
-  "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright",
-  "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis",
-  "fraction","currency","guilsinglleft","guilsinglright","fi","fl",
-  "daggerdbl","periodcentered","quotesinglbase","quotedblbase",
-  "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave",
-  "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex",
-  "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi",
-  "circumflex","tilde","macron","breve","dotaccent","ring","cedilla",
-  "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron",
-  "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn",
-  "thorn","minus","multiply","onesuperior","twosuperior","threesuperior",
-  "onehalf","onequarter","threequarters","franc","Gbreve","gbreve",
-  "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron",
-  "dcroat",
-}
-local weights={
-  [100]="thin",
-  [200]="extralight",
-  [300]="light",
-  [400]="normal",
-  [500]="medium",
-  [600]="semibold",
-  [700]="bold",
-  [800]="extrabold",
-  [900]="black",
-}
-local widths={
-  [1]="ultracondensed",
-  [2]="extracondensed",
-  [3]="condensed",
-  [4]="semicondensed",
-  [5]="normal",
-  [6]="semiexpanded",
-  [7]="expanded",
-  [8]="extraexpanded",
-  [9]="ultraexpanded",
-}
-setmetatableindex(weights,function(t,k)
-  local r=floor((k+50)/100)*100
-  local v=(r>900 and "black") or rawget(t,r) or "normal"
-  return v
-end)
-setmetatableindex(widths,function(t,k)
-  return "normal"
-end)
-local panoseweights={
-  [ 0]="normal",
-  [ 1]="normal",
-  [ 2]="verylight",
-  [ 3]="light",
-  [ 4]="thin",
-  [ 5]="book",
-  [ 6]="medium",
-  [ 7]="demi",
-  [ 8]="bold",
-  [ 9]="heavy",
-  [10]="black",
-}
-local panosewidths={
-  [ 0]="normal",
-  [ 1]="normal",
-  [ 2]="normal",
-  [ 3]="normal",
-  [ 4]="normal",
-  [ 5]="expanded",
-  [ 6]="condensed",
-  [ 7]="veryexpanded",
-  [ 8]="verycondensed",
-  [ 9]="monospaced",
-}
-local platformnames={
-  postscriptname=true,
-  fullname=true,
-  family=true,
-  subfamily=true,
-  typographicfamily=true,
-  typographicsubfamily=true,
-  compatiblefullname=true,
-}
-function readers.name(f,fontdata,specification)
-  local datatable=fontdata.tables.name
-  if datatable then
-    setposition(f,datatable.offset)
-    local format=readushort(f)
-    local nofnames=readushort(f)
-    local offset=readushort(f)
-    local start=datatable.offset+offset
-    local namelists={
-      unicode={},
-      windows={},
-      macintosh={},
-    }
-    for i=1,nofnames do
-      local platform=platforms[readushort(f)]
-      if platform then
-        local namelist=namelists[platform]
-        if namelist then
-          local encoding=readushort(f)
-          local language=readushort(f)
-          local encodings=encodings[platform]
-          local languages=languages[platform]
-          if encodings and languages then
-            local encoding=encodings[encoding]
-            local language=languages[language]
-            if encoding and language then
-              local name=reservednames[readushort(f)]
-              if name then
-                namelist[#namelist+1]={
-                  platform=platform,
-                  encoding=encoding,
-                  language=language,
-                  name=name,
-                  length=readushort(f),
-                  offset=start+readushort(f),
-                }
-              else
-                skipshort(f,2)
-              end
-            else
-              skipshort(f,3)
-            end
-          else
-            skipshort(f,3)
-          end
-        else
-          skipshort(f,5)
-        end
-      else
-        skipshort(f,5)
-      end
-    end
-    local names={}
-    local done={}
-    local function filter(platform,e,l)
-      local namelist=namelists[platform]
-      for i=1,#namelist do
-        local name=namelist[i]
-        local nametag=name.name
-        if not done[nametag] then
-          local encoding=name.encoding
-          local language=name.language
-          if (not e or encoding==e) and (not l or language==l) then
-            setposition(f,name.offset)
-            local content=readstring(f,name.length)
-            local decoder=decoders[platform]
-            if decoder then
-              decoder=decoder[encoding]
-            end
-            if decoder then
-              content=decoder(content)
-            end
-            names[nametag]={
-              content=content,
-              platform=platform,
-              encoding=encoding,
-              language=language,
-            }
-            done[nametag]=true
-          end
-        end
-      end
-    end
-    filter("windows","unicode bmp","english - united states")
-    filter("macintosh","roman","english")
-    filter("windows")
-    filter("macintosh")
-    filter("unicode")
-    fontdata.names=names
-    if specification.platformnames then
-      local collected={}
-      for platform,namelist in next,namelists do
-        local filtered=false
-        for i=1,#namelist do
-          local entry=namelist[i]
-          local name=entry.name
-          if platformnames[name] then
-            setposition(f,entry.offset)
-            local content=readstring(f,entry.length)
-            local encoding=entry.encoding
-            local decoder=decoders[platform]
-            if decoder then
-              decoder=decoder[encoding]
-            end
-            if decoder then
-              content=decoder(content)
-            end
-            if filtered then
-              filtered[name]=content
-            else
-              filtered={ [name]=content }
-            end
-          end
-        end
-        if filtered then
-          collected[platform]=filtered
-        end
-      end
-      fontdata.platformnames=collected
-    end
-  else
-    fontdata.names={}
-  end
-end
-local validutf=lpeg.patterns.validutf8
-local function getname(fontdata,key)
-  local names=fontdata.names
-  if names then
-    local value=names[key]
-    if value then
-      local content=value.content
-      return lpegmatch(validutf,content) and content or nil
-    end
-  end
-end
-readers["os/2"]=function(f,fontdata)
-  local datatable=fontdata.tables["os/2"]
-  if datatable then
-    setposition(f,datatable.offset)
-    local version=readushort(f)
-    local windowsmetrics={
-      version=version,
-      averagewidth=readshort(f),
-      weightclass=readushort(f),
-      widthclass=readushort(f),
-      fstype=readushort(f),
-      subscriptxsize=readshort(f),
-      subscriptysize=readshort(f),
-      subscriptxoffset=readshort(f),
-      subscriptyoffset=readshort(f),
-      superscriptxsize=readshort(f),
-      superscriptysize=readshort(f),
-      superscriptxoffset=readshort(f),
-      superscriptyoffset=readshort(f),
-      strikeoutsize=readshort(f),
-      strikeoutpos=readshort(f),
-      familyclass=readshort(f),
-      panose={ readbytes(f,10) },
-      unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) },
-      vendor=readstring(f,4),
-      fsselection=readushort(f),
-      firstcharindex=readushort(f),
-      lastcharindex=readushort(f),
-      typoascender=readshort(f),
-      typodescender=readshort(f),
-      typolinegap=readshort(f),
-      winascent=readushort(f),
-      windescent=readushort(f),
-    }
-    if version>=1 then
-      windowsmetrics.codepageranges={ readulong(f),readulong(f) }
-    end
-    if version>=3 then
-      windowsmetrics.xheight=readshort(f)
-      windowsmetrics.capheight=readshort(f)
-      windowsmetrics.defaultchar=readushort(f)
-      windowsmetrics.breakchar=readushort(f)
-    end
-    windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass]
-    windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass]
-    windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]]
-    windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]]
-    fontdata.windowsmetrics=windowsmetrics
-  else
-    fontdata.windowsmetrics={}
-  end
-end
-readers.head=function(f,fontdata)
-  local datatable=fontdata.tables.head
-  if datatable then
-    setposition(f,datatable.offset)
-    local fontheader={
-      version=readfixed(f),
-      revision=readfixed(f),
-      checksum=readulong(f),
-      magic=readulong(f),
-      flags=readushort(f),
-      units=readushort(f),
-      created=readlongdatetime(f),
-      modified=readlongdatetime(f),
-      xmin=readshort(f),
-      ymin=readshort(f),
-      xmax=readshort(f),
-      ymax=readshort(f),
-      macstyle=readushort(f),
-      smallpixels=readushort(f),
-      directionhint=readshort(f),
-      indextolocformat=readshort(f),
-      glyphformat=readshort(f),
-    }
-    fontdata.fontheader=fontheader
-  else
-    fontdata.fontheader={}
-  end
-  fontdata.nofglyphs=0
-end
-readers.hhea=function(f,fontdata,specification)
-  if specification.details then
-    local datatable=fontdata.tables.hhea
-    if datatable then
-      setposition(f,datatable.offset)
-      fontdata.horizontalheader={
-        version=readfixed(f),
-        ascender=readfword(f),
-        descender=readfword(f),
-        linegap=readfword(f),
-        maxadvancewidth=readufword(f),
-        minleftsidebearing=readfword(f),
-        minrightsidebearing=readfword(f),
-        maxextent=readfword(f),
-        caretsloperise=readshort(f),
-        caretsloperun=readshort(f),
-        caretoffset=readshort(f),
-        reserved_1=readshort(f),
-        reserved_2=readshort(f),
-        reserved_3=readshort(f),
-        reserved_4=readshort(f),
-        metricdataformat=readshort(f),
-        nofmetrics=readushort(f),
-      }
-    else
-      fontdata.horizontalheader={
-        nofmetrics=0,
-      }
-    end
-  end
-end
-readers.vhea=function(f,fontdata,specification)
-  if specification.details then
-    local datatable=fontdata.tables.vhea
-    if datatable then
-      setposition(f,datatable.offset)
-      local version=readfixed(f)
-      fontdata.verticalheader={
-        version=version,
-        ascender=readfword(f),
-        descender=readfword(f),
-        linegap=readfword(f),
-        maxadvanceheight=readufword(f),
-        mintopsidebearing=readfword(f),
-        minbottomsidebearing=readfword(f),
-        maxextent=readfword(f),
-        caretsloperise=readshort(f),
-        caretsloperun=readshort(f),
-        caretoffset=readshort(f),
-        reserved_1=readshort(f),
-        reserved_2=readshort(f),
-        reserved_3=readshort(f),
-        reserved_4=readshort(f),
-        metricdataformat=readshort(f),
-        nofmetrics=readushort(f),
-      }
-    else
-      fontdata.verticalheader={
-        nofmetrics=0,
-      }
-    end
-  end
-end
-readers.maxp=function(f,fontdata,specification)
-  if specification.details then
-    local datatable=fontdata.tables.maxp
-    if datatable then
-      setposition(f,datatable.offset)
-      local version=readfixed(f)
-      local nofglyphs=readushort(f)
-      fontdata.nofglyphs=nofglyphs
-      if version==0.5 then
-        fontdata.maximumprofile={
-          version=version,
-          nofglyphs=nofglyphs,
-        }
-        return
-      elseif version==1.0 then
-        fontdata.maximumprofile={
-          version=version,
-          nofglyphs=nofglyphs,
-          points=readushort(f),
-          contours=readushort(f),
-          compositepoints=readushort(f),
-          compositecontours=readushort(f),
-          zones=readushort(f),
-          twilightpoints=readushort(f),
-          storage=readushort(f),
-          functiondefs=readushort(f),
-          instructiondefs=readushort(f),
-          stackelements=readushort(f),
-          sizeofinstructions=readushort(f),
-          componentelements=readushort(f),
-          componentdepth=readushort(f),
-        }
-        return
-      end
-    end
-    fontdata.maximumprofile={
-      version=version,
-      nofglyphs=0,
-    }
-  end
-end
-readers.hmtx=function(f,fontdata,specification)
-  if specification.glyphs then
-    local datatable=fontdata.tables.hmtx
-    if datatable then
-      setposition(f,datatable.offset)
-      local horizontalheader=fontdata.horizontalheader
-      local nofmetrics=horizontalheader.nofmetrics
-      local glyphs=fontdata.glyphs
-      local nofglyphs=fontdata.nofglyphs
-      local width=0 
-      local leftsidebearing=0
-      for i=0,nofmetrics-1 do
-        local glyph=glyphs[i]
-        width=readshort(f)
-        leftsidebearing=readshort(f)
-        if width~=0 then
-          glyph.width=width
-        end
-      end
-      for i=nofmetrics,nofglyphs-1 do
-        local glyph=glyphs[i]
-        if width~=0 then
-          glyph.width=width
-        end
-      end
-    end
-  end
-end
-readers.vmtx=function(f,fontdata,specification)
-  if specification.glyphs then
-    local datatable=fontdata.tables.vmtx
-    if datatable then
-      setposition(f,datatable.offset)
-      local verticalheader=fontdata.verticalheader
-      local nofmetrics=verticalheader.nofmetrics
-      local glyphs=fontdata.glyphs
-      local nofglyphs=fontdata.nofglyphs
-      local vheight=0
-      local vdefault=verticalheader.ascender+verticalheader.descender
-      local topsidebearing=0
-      for i=0,nofmetrics-1 do
-        local glyph=glyphs[i]
-        vheight=readshort(f)
-        topsidebearing=readshort(f)
-        if vheight~=0 and vheight~=vdefault then
-          glyph.vheight=vheight
-        end
-      end
-      for i=nofmetrics,nofglyphs-1 do
-        local glyph=glyphs[i]
-        if vheight~=0 and vheight~=vdefault then
-          glyph.vheight=vheight
-        end
-      end
-    end
-  end
-end
-readers.vorg=function(f,fontdata,specification)
-  if specification.glyphs then
-    local datatable=fontdata.tables.vorg
-    if datatable then
-      report("todo: %s","vorg")
-    end
-  end
-end
-readers.post=function(f,fontdata,specification)
-  local datatable=fontdata.tables.post
-  if datatable then
-    setposition(f,datatable.offset)
-    local version=readfixed(f)
-    fontdata.postscript={
-      version=version,
-      italicangle=round(1000*readfixed(f))/1000,
-      underlineposition=readfword(f),
-      underlinethickness=readfword(f),
-      monospaced=readulong(f),
-      minmemtype42=readulong(f),
-      maxmemtype42=readulong(f),
-      minmemtype1=readulong(f),
-      maxmemtype1=readulong(f),
-    }
-    if not specification.glyphs then
-    elseif version==1.0 then
-      for index=0,#standardromanencoding do
-        glyphs[index].name=standardromanencoding[index]
-      end
-    elseif version==2.0 then
-      local glyphs=fontdata.glyphs
-      local nofglyphs=readushort(f)
-      local indices={}
-      local names={}
-      local maxnames=0
-      for i=0,nofglyphs-1 do
-        local nameindex=readushort(f)
-        if nameindex>=258 then
-          maxnames=maxnames+1
-          nameindex=nameindex-257
-          indices[nameindex]=i
-        else
-          glyphs[i].name=standardromanencoding[nameindex]
-        end
-      end
-      for i=1,maxnames do
-        local mapping=indices[i]
-        if not mapping then
-          report("quit post name fetching at %a of %a: %s",i,maxnames,"no index")
-          break
-        else
-          local length=readbyte(f)
-          if length>0 then
-            glyphs[mapping].name=readstring(f,length)
-          else
-            report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow")
-            break
-          end
-        end
-      end
-    elseif version==2.5 then
-    elseif version==3.0 then
-    end
-  else
-    fontdata.postscript={}
-  end
-end
-readers.cff=function(f,fontdata,specification)
-  if specification.glyphs then
-    reportskippedtable("cff")
-  end
-end
-local formatreaders={}
-local duplicatestoo=true
-local sequence={
-  { 3,1,4 },
-  { 3,10,12 },
-  { 0,3,4 },
-  { 0,1,4 },
-  { 0,0,6 },
-  { 3,0,6 },
-  { 0,5,14 },
-  { 3,10,13 },
-}
-local supported={}
-for i=1,#sequence do
-  local sp,se,sf=unpack(sequence[i])
-  local p=supported[sp]
-  if not p then
-    p={}
-    supported[sp]=p
-  end
-  local e=p[se]
-  if not e then
-    e={}
-    p[se]=e
-  end
-  e[sf]=true
-end
-formatreaders[4]=function(f,fontdata,offset)
-  setposition(f,offset+2)
-  local length=readushort(f) 
-  local language=readushort(f)
-  local nofsegments=readushort(f)/2
-  skipshort(f,3)
-  local endchars={}
-  local startchars={}
-  local deltas={}
-  local offsets={}
-  local indices={}
-  local mapping=fontdata.mapping
-  local glyphs=fontdata.glyphs
-  local duplicates=fontdata.duplicates
-  local nofdone=0
-  for i=1,nofsegments do
-    endchars[i]=readushort(f)
-  end
-  local reserved=readushort(f) 
-  for i=1,nofsegments do
-    startchars[i]=readushort(f)
-  end
-  for i=1,nofsegments do
-    deltas[i]=readshort(f)
-  end
-  for i=1,nofsegments do
-    offsets[i]=readushort(f)
-  end
-  local size=(length-2*2-5*2-4*nofsegments*2)/2
-  for i=1,size-1 do
-    indices[i]=readushort(f)
-  end
-  for segment=1,nofsegments do
-    local startchar=startchars[segment]
-    local endchar=endchars[segment]
-    local offset=offsets[segment]
-    local delta=deltas[segment]
-    if startchar==0xFFFF and endchar==0xFFFF then
-    elseif startchar==0xFFFF and offset==0 then
-    elseif offset==0xFFFF then
-    elseif offset==0 then
-      if trace_cmap then
-        report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536)
-      end
-      for unicode=startchar,endchar do
-        local index=(unicode+delta)%65536
-        if index and index>0 then
-          local glyph=glyphs[index]
-          if glyph then
-            local gu=glyph.unicode
-            if not gu then
-              glyph.unicode=unicode
-              nofdone=nofdone+1
-            elseif gu~=unicode then
-              if duplicatestoo then
-                local d=duplicates[gu]
-                if d then
-                  d[unicode]=true
-                else
-                  duplicates[gu]={ [unicode]=true }
-                end
-              else
-                report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name)
-              end
-            end
-            if not mapping[index] then
-              mapping[index]=unicode
-            end
-          end
-        end
-      end
-    else
-      local shift=(segment-nofsegments+offset/2)-startchar
-      if trace_cmap then
-        report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536)
-      end
-      for unicode=startchar,endchar do
-        local slot=shift+unicode
-        local index=indices[slot]
-        if index and index>0 then
-          index=(index+delta)%65536
-          local glyph=glyphs[index]
-          if glyph then
-            local gu=glyph.unicode
-            if not gu then
-              glyph.unicode=unicode
-              nofdone=nofdone+1
-            elseif gu~=unicode then
-              if duplicatestoo then
-                local d=duplicates[gu]
-                if d then
-                  d[unicode]=true
-                else
-                  duplicates[gu]={ [unicode]=true }
-                end
-              else
-                report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name)
-              end
-            end
-            if not mapping[index] then
-              mapping[index]=unicode
-            end
-          end
-        end
-      end
-    end
-  end
-  return nofdone
-end
-formatreaders[6]=function(f,fontdata,offset)
-  setposition(f,offset) 
-  local format=readushort(f)
-  local length=readushort(f)
-  local language=readushort(f)
-  local mapping=fontdata.mapping
-  local glyphs=fontdata.glyphs
-  local duplicates=fontdata.duplicates
-  local start=readushort(f)
-  local count=readushort(f)
-  local stop=start+count-1
-  local nofdone=0
-  if trace_cmap then
-    report("format 6 from %C to %C",2,start,stop)
-  end
-  for unicode=start,stop do
-    local index=readushort(f)
-    if index>0 then
-      local glyph=glyphs[index]
-      if glyph then
-        local gu=glyph.unicode
-        if not gu then
-          glyph.unicode=unicode
-          nofdone=nofdone+1
-        elseif gu~=unicode then
-        end
-        if not mapping[index] then
-          mapping[index]=unicode
-        end
-      end
-    end
-  end
-  return nofdone
-end
-formatreaders[12]=function(f,fontdata,offset)
-  setposition(f,offset+2+2+4+4) 
-  local mapping=fontdata.mapping
-  local glyphs=fontdata.glyphs
-  local duplicates=fontdata.duplicates
-  local nofgroups=readulong(f)
-  local nofdone=0
-  for i=1,nofgroups do
-    local first=readulong(f)
-    local last=readulong(f)
-    local index=readulong(f)
-    if trace_cmap then
-      report("format 12 from %C to %C starts at index %i",first,last,index)
-    end
-    for unicode=first,last do
-      local glyph=glyphs[index]
-      if glyph then
-        local gu=glyph.unicode
-        if not gu then
-          glyph.unicode=unicode
-          nofdone=nofdone+1
-        elseif gu~=unicode then
-          local d=duplicates[gu]
-          if d then
-            d[unicode]=true
-          else
-            duplicates[gu]={ [unicode]=true }
-          end
-        end
-        if not mapping[index] then
-          mapping[index]=unicode
-        end
-      end
-      index=index+1
-    end
-  end
-  return nofdone
-end
-formatreaders[13]=function(f,fontdata,offset)
-  setposition(f,offset+2+2+4+4) 
-  local mapping=fontdata.mapping
-  local glyphs=fontdata.glyphs
-  local duplicates=fontdata.duplicates
-  local nofgroups=readulong(f)
-  local nofdone=0
-  for i=1,nofgroups do
-    local first=readulong(f)
-    local last=readulong(f)
-    local index=readulong(f)
-    if first<privateoffset then
-      if trace_cmap then
-        report("format 13 from %C to %C get index %i",first,last,index)
-      end
-      local glyph=glyphs[index]
-      local unicode=glyph.unicode
-      if not unicode then
-        unicode=first
-        glyph.unicode=unicode
-        first=first+1
-      end
-      local list=duplicates[unicode]
-      mapping[index]=unicode
-      if not list then
-        list={}
-        duplicates[unicode]=list
-      end
-      if last>=privateoffset then
-        local limit=privateoffset-1
-        report("format 13 from %C to %C pruned to %C",first,last,limit)
-        last=limit
-      end
-      for unicode=first,last do
-        list[unicode]=true
-      end
-      nofdone=nofdone+last-first+1
-    else
-      report("format 13 from %C to %C ignored",first,last)
-    end
-  end
-  return nofdone
-end
-formatreaders[14]=function(f,fontdata,offset)
-  if offset and offset~=0 then
-    setposition(f,offset)
-    local format=readushort(f)
-    local length=readulong(f)
-    local nofrecords=readulong(f)
-    local records={}
-    local variants={}
-    local nofdone=0
-    fontdata.variants=variants
-    for i=1,nofrecords do
-      records[i]={
-        selector=readuint(f),
-        default=readulong(f),
-        other=readulong(f),
-      }
-    end
-    for i=1,nofrecords do
-      local record=records[i]
-      local selector=record.selector
-      local default=record.default
-      local other=record.other
-      local other=record.other
-      if other~=0 then
-        setposition(f,offset+other)
-        local mapping={}
-        local count=readulong(f)
-        for i=1,count do
-          mapping[readuint(f)]=readushort(f)
-        end
-        nofdone=nofdone+count
-        variants[selector]=mapping
-      end
-    end
-    return nofdone
-  else
-    return 0
-  end
-end
-local function checkcmap(f,fontdata,records,platform,encoding,format)
-  local data=records[platform]
-  if not data then
-    return 0
-  end
-  data=data[encoding]
-  if not data then
-    return 0
-  end
-  data=data[format]
-  if not data then
-    return 0
-  end
-  local reader=formatreaders[format]
-  if not reader then
-    return 0
-  end
-  local p=platforms[platform]
-  local e=encodings[p]
-  local n=reader(f,fontdata,data) or 0
-  report("cmap checked: platform %i (%s), encoding %i (%s), format %i, new unicodes %i",platform,p,encoding,e and e[encoding] or "?",format,n)
-  return n
-end
-function readers.cmap(f,fontdata,specification)
-  if specification.glyphs then
-    local datatable=fontdata.tables.cmap
-    if datatable then
-      local tableoffset=datatable.offset
-      setposition(f,tableoffset)
-      local version=readushort(f)
-      local noftables=readushort(f)
-      local records={}
-      local unicodecid=false
-      local variantcid=false
-      local variants={}
-      local duplicates=fontdata.duplicates or {}
-      fontdata.duplicates=duplicates
-      for i=1,noftables do
-        local platform=readushort(f)
-        local encoding=readushort(f)
-        local offset=readulong(f)
-        local record=records[platform]
-        if not record then
-          records[platform]={
-            [encoding]={
-              offsets={ offset },
-              formats={},
-            }
-          }
-        else
-          local subtables=record[encoding]
-          if not subtables then
-            record[encoding]={
-              offsets={ offset },
-              formats={},
-            }
-          else
-            local offsets=subtables.offsets
-            offsets[#offsets+1]=offset
-          end
-        end
-      end
-      report("found cmaps:")
-      for platform,record in sortedhash(records) do
-        local p=platforms[platform]
-        local e=encodings[p]
-        local sp=supported[platform]
-        local ps=p or "?"
-        if sp then
-          report("  platform %i: %s",platform,ps)
-        else
-          report("  platform %i: %s (unsupported)",platform,ps)
-        end
-        for encoding,subtables in sortedhash(record) do
-          local se=sp and sp[encoding]
-          local es=e and e[encoding] or "?"
-          if se then
-            report("    encoding %i: %s",encoding,es)
-          else
-            report("    encoding %i: %s (unsupported)",encoding,es)
-          end
-          local offsets=subtables.offsets
-          local formats=subtables.formats
-          for i=1,#offsets do
-            local offset=tableoffset+offsets[i]
-            setposition(f,offset)
-            formats[readushort(f)]=offset
-          end
-          record[encoding]=formats
-          local list=sortedkeys(formats)
-          for i=1,#list do
-            if not (se and se[list[i]]) then
-              list[i]=list[i].." (unsupported)"
-            end
-          end
-          report("      formats: % t",list)
-        end
-      end
-      local ok=false
-      for i=1,#sequence do
-        local sp,se,sf=unpack(sequence[i])
-        if checkcmap(f,fontdata,records,sp,se,sf)>0 then
-          ok=true
-        end
-      end
-      if not ok then
-        report("no useable unicode cmap found")
-      end
-      fontdata.cidmaps={
-        version=version,
-        noftables=noftables,
-        records=records,
-      }
-    else
-      fontdata.cidmaps={}
-    end
-  end
-end
-function readers.loca(f,fontdata,specification)
-  if specification.glyphs then
-    reportskippedtable("loca")
-  end
-end
-function readers.glyf(f,fontdata,specification) 
-  if specification.glyphs then
-    reportskippedtable("glyf")
-  end
-end
-function readers.colr(f,fontdata,specification)
-  if specification.glyphs then
-    reportskippedtable("colr")
-  end
-end
-function readers.cpal(f,fontdata,specification)
-  if specification.glyphs then
-    reportskippedtable("cpal")
-  end
-end
-function readers.svg(f,fontdata,specification)
-  if specification.glyphs then
-    reportskippedtable("svg")
-  end
-end
-function readers.kern(f,fontdata,specification)
-  if specification.kerns then
-    local datatable=fontdata.tables.kern
-    if datatable then
-      setposition(f,datatable.offset)
-      local version=readushort(f)
-      local noftables=readushort(f)
-      for i=1,noftables do
-        local version=readushort(f)
-        local length=readushort(f)
-        local coverage=readushort(f)
-        local format=bit32.rshift(coverage,8) 
-        if format==0 then
-          local nofpairs=readushort(f)
-          local searchrange=readushort(f)
-          local entryselector=readushort(f)
-          local rangeshift=readushort(f)
-          local kerns={}
-          local glyphs=fontdata.glyphs
-          for i=1,nofpairs do
-            local left=readushort(f)
-            local right=readushort(f)
-            local kern=readfword(f)
-            local glyph=glyphs[left]
-            local kerns=glyph.kerns
-            if kerns then
-              kerns[right]=kern
-            else
-              glyph.kerns={ [right]=kern }
-            end
-          end
-        elseif format==2 then
-          report("todo: kern classes")
-        else
-          report("todo: kerns")
-        end
-      end
-    end
-  end
-end
-function readers.gdef(f,fontdata,specification)
-  if specification.details then
-    reportskippedtable("gdef")
-  end
-end
-function readers.gsub(f,fontdata,specification)
-  if specification.details then
-    reportskippedtable("gsub")
-  end
-end
-function readers.gpos(f,fontdata,specification)
-  if specification.details then
-    reportskippedtable("gpos")
-  end
-end
-function readers.math(f,fontdata,specification)
-  if specification.glyphs then
-    reportskippedtable("math")
-  end
-end
-local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo)
-  local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata
-  local names=fontdata.names
-  local info=nil
-  if names then
-    local metrics=fontdata.windowsmetrics or {}
-    local postscript=fontdata.postscript   or {}
-    local fontheader=fontdata.fontheader   or {}
-    local cffinfo=fontdata.cffinfo    or {}
-    local filename=fontdata.filename
-    local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight)
-    local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width )
-    local fontname=getname(fontdata,"postscriptname")
-    local fullname=getname(fontdata,"fullname")
-    local family=getname(fontdata,"family")
-    local subfamily=getname(fontdata,"subfamily")
-    local familyname=getname(fontdata,"typographicfamily")
-    local subfamilyname=getname(fontdata,"typographicsubfamily")
-    local compatiblename=getname(fontdata,"compatiblefullname") 
-    if rawfamilynames then
-    else
-      if not  familyname then  familyname=family end
-      if not subfamilyname then subfamilyname=subfamily end
-    end
-    info={ 
-      subfontindex=fontdata.subfontindex or sub or 0,
-      version=getname(fontdata,"version"),
-      fontname=fontname,
-      fullname=fullname,
-      family=family,
-      subfamily=subfamily,
-      familyname=familyname,
-      subfamilyname=subfamilyname,
-      compatiblename=compatiblename,
-      weight=weight and lower(weight),
-      width=width and lower(width),
-      pfmweight=metrics.weightclass or 400,
-      pfmwidth=metrics.widthclass or 5,
-      panosewidth=metrics.panosewidth,
-      panoseweight=metrics.panoseweight,
-      italicangle=postscript.italicangle or 0,
-      units=fontheader.units or 0,
-      designsize=fontdata.designsize,
-      minsize=fontdata.minsize,
-      maxsize=fontdata.maxsize,
-      monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced",
-      averagewidth=metrics.averagewidth,
-      xheight=metrics.xheight,
-      capheight=metrics.capheight,
-      ascender=metrics.typoascender,
-      descender=metrics.typodescender,
-      platformnames=platformnames and fontdata.platformnames or nil,
-    }
-    if metricstoo then
-      local keys={
-        "version",
-        "ascender","descender","linegap",
-        "maxadvancewidth","maxadvanceheight","maxextent",
-        "minbottomsidebearing","mintopsidebearing",
-      }
-      local h=fontdata.horizontalheader or {}
-      local v=fontdata.verticalheader  or {}
-      if h then
-        local th={}
-        local tv={}
-        for i=1,#keys do
-          local key=keys[i]
-          th[key]=h[key] or 0
-          tv[key]=v[key] or 0
-        end
-        info.horizontalmetrics=th
-        info.verticalmetrics=tv
-      end
-    end
-  elseif n then
-    info={
-      filename=fontdata.filename,
-      comment="there is no info for subfont "..n,
-    }
-  else
-    info={
-      filename=fontdata.filename,
-      comment="there is no info",
-    }
-  end
-  return info
-end
-local function loadtables(f,specification,offset)
-  if offset then
-    setposition(f,offset)
-  end
-  local tables={}
-  local basename=file.basename(specification.filename)
-  local filesize=specification.filesize
-  local filetime=specification.filetime
-  local fontdata={ 
-    filename=basename,
-    filesize=filesize,
-    filetime=filetime,
-    version=readstring(f,4),
-    noftables=readushort(f),
-    searchrange=readushort(f),
-    entryselector=readushort(f),
-    rangeshift=readushort(f),
-    tables=tables,
-  }
-  for i=1,fontdata.noftables do
-    local tag=lower(stripstring(readstring(f,4)))
-    local checksum=readulong(f) 
-    local offset=readulong(f)
-    local length=readulong(f)
-    if offset+length>filesize then
-      report("bad %a table in file %a",tag,basename)
-    end
-    tables[tag]={
-      checksum=checksum,
-      offset=offset,
-      length=length,
-    }
-  end
-  if tables.cff then
-    fontdata.format="opentype"
-  else
-    fontdata.format="truetype"
-  end
-  return fontdata
-end
-local function prepareglyps(fontdata)
-  local glyphs=setmetatableindex(function(t,k)
-    local v={
-      index=k,
-    }
-    t[k]=v
-    return v
-  end)
-  fontdata.glyphs=glyphs
-  fontdata.mapping={}
-end
-local function readdata(f,offset,specification)
-  local fontdata=loadtables(f,specification,offset)
-  if specification.glyphs then
-    prepareglyps(fontdata)
-  end
-  readers["name"](f,fontdata,specification)
-  local askedname=specification.askedname
-  if askedname then
-    local fullname=getname(fontdata,"fullname") or ""
-    local cleanname=gsub(askedname,"[^a-zA-Z0-9]","")
-    local foundname=gsub(fullname,"[^a-zA-Z0-9]","")
-    if lower(cleanname)~=lower(foundname) then
-      return 
-    end
-  end
-  readers["os/2"](f,fontdata,specification)
-  readers["head"](f,fontdata,specification)
-  readers["maxp"](f,fontdata,specification)
-  readers["hhea"](f,fontdata,specification)
-  readers["vhea"](f,fontdata,specification)
-  readers["hmtx"](f,fontdata,specification)
-  readers["vmtx"](f,fontdata,specification)
-  readers["vorg"](f,fontdata,specification)
-  readers["post"](f,fontdata,specification)
-  readers["cff" ](f,fontdata,specification)
-  readers["cmap"](f,fontdata,specification)
-  readers["loca"](f,fontdata,specification)
-  readers["glyf"](f,fontdata,specification)
-  readers["colr"](f,fontdata,specification)
-  readers["cpal"](f,fontdata,specification)
-  readers["svg" ](f,fontdata,specification)
-  readers["kern"](f,fontdata,specification)
-  readers["gdef"](f,fontdata,specification)
-  readers["gsub"](f,fontdata,specification)
-  readers["gpos"](f,fontdata,specification)
-  readers["math"](f,fontdata,specification)
-  fontdata.locations=nil
-  fontdata.tables=nil
-  fontdata.cidmaps=nil
-  fontdata.dictionaries=nil
-  return fontdata
-end
-local function loadfontdata(specification)
-  local filename=specification.filename
-  local fileattr=lfs.attributes(filename)
-  local filesize=fileattr and fileattr.size or 0
-  local filetime=fileattr and fileattr.modification or 0
-  local f=openfile(filename,true) 
-  if not f then
-    report("unable to open %a",filename)
-  elseif filesize==0 then
-    report("empty file %a",filename)
-    closefile(f)
-  else
-    specification.filesize=filesize
-    specification.filetime=filetime
-    local version=readstring(f,4)
-    local fontdata=nil
-    if version=="OTTO" or version=="true" or version=="\0\1\0\0" then
-      fontdata=readdata(f,0,specification)
-    elseif version=="ttcf" then
-      local subfont=tonumber(specification.subfont)
-      local offsets={}
-      local ttcversion=readulong(f)
-      local nofsubfonts=readulong(f)
-      for i=1,nofsubfonts do
-        offsets[i]=readulong(f)
-      end
-      if subfont then 
-        if subfont>=1 and subfont<=nofsubfonts then
-          fontdata=readdata(f,offsets[subfont],specification)
-        else
-          report("no subfont %a in file %a",subfont,filename)
-        end
-      else
-        subfont=specification.subfont
-        if type(subfont)=="string" and subfont~="" then
-          specification.askedname=subfont
-          for i=1,nofsubfonts do
-            fontdata=readdata(f,offsets[i],specification)
-            if fontdata then
-              fontdata.subfontindex=i
-              report("subfont named %a has index %a",subfont,i)
-              break
-            end
-          end
-          if not fontdata then
-            report("no subfont named %a",subfont)
-          end
-        else
-          local subfonts={}
-          fontdata={
-            filename=filename,
-            filesize=filesize,
-            filetime=filetime,
-            version=version,
-            subfonts=subfonts,
-            ttcversion=ttcversion,
-            nofsubfonts=nofsubfonts,
-          }
-          for i=1,nofsubfonts do
-            subfonts[i]=readdata(f,offsets[i],specification)
-          end
-        end
-      end
-    else
-      report("unknown version %a in file %a",version,filename)
-    end
-    closefile(f)
-    return fontdata or {}
-  end
-end
-local function loadfont(specification,n)
-  if type(specification)=="string" then
-    specification={
-      filename=specification,
-      info=true,
-      details=true,
-      glyphs=true,
-      shapes=true,
-      kerns=true,
-      globalkerns=true,
-      lookups=true,
-      subfont=n or true,
-      tounicode=false,
-    }
-  end
-  if specification.shapes or specification.lookups or specification.kerns then
-    specification.glyphs=true
-  end
-  if specification.glyphs then
-    specification.details=true
-  end
-  if specification.details then
-    specification.info=true 
-  end
-  if specification.platformnames then
-    specification.platformnames=true 
-  end
-  local function message(str)
-    report("fatal error in file %a: %s\n%s",specification.filename,str,debug.traceback())
-  end
-  local ok,result=xpcall(loadfontdata,message,specification)
-  if ok then
-    return result
-  end
-end
-function readers.loadshapes(filename,n)
-  local fontdata=loadfont {
-    filename=filename,
-    shapes=true,
-    subfont=n,
-  }
-  if fontdata then
-    for k,v in next,fontdata.glyphs do
-      v.class=nil
-      v.index=nil
-      v.math=nil
-    end
-  end
-  return fontdata and {
-    filename=filename,
-    format=fontdata.format,
-    glyphs=fontdata.glyphs,
-    units=fontdata.fontheader.units,
-  } or {
-    filename=filename,
-    format="unknown",
-    glyphs={},
-    units=0,
-  }
-end
-function readers.loadfont(filename,n)
-  local fontdata=loadfont {
-    filename=filename,
-    glyphs=true,
-    shapes=false,
-    lookups=true,
-    subfont=n,
-  }
-  if fontdata then
-    return {
-      tableversion=tableversion,
-      creator="context mkiv",
-      size=fontdata.filesize,
-      time=fontdata.filetime,
-      glyphs=fontdata.glyphs,
-      descriptions=fontdata.descriptions,
-      format=fontdata.format,
-      goodies={},
-      metadata=getinfo(fontdata,n,false,false,true),
-      properties={
-        hasitalics=fontdata.hasitalics or false,
-        maxcolorclass=fontdata.maxcolorclass,
-        hascolor=fontdata.hascolor or false,
-      },
-      resources={
-        filename=filename,
-        private=privateoffset,
-        duplicates=fontdata.duplicates or {},
-        features=fontdata.features  or {},
-        sublookups=fontdata.sublookups or {},
-        marks=fontdata.marks    or {},
-        markclasses=fontdata.markclasses or {},
-        marksets=fontdata.marksets  or {},
-        sequences=fontdata.sequences  or {},
-        variants=fontdata.variants,
-        version=getname(fontdata,"version"),
-        cidinfo=fontdata.cidinfo,
-        mathconstants=fontdata.mathconstants,
-        colorpalettes=fontdata.colorpalettes,
-        svgshapes=fontdata.svgshapes,
-      },
-    }
-  end
-end
-function readers.getinfo(filename,specification)
-  local subfont=nil
-  local platformnames=false
-  local rawfamilynames=false
-  if type(specification)=="table" then
-    subfont=tonumber(specification.subfont)
-    platformnames=specification.platformnames
-    rawfamilynames=specification.rawfamilynames
-  else
-    subfont=tonumber(specification)
-  end
-  local fontdata=loadfont {
-    filename=filename,
-    details=true,
-    platformnames=platformnames,
-  }
-  if fontdata then
-    local subfonts=fontdata.subfonts
-    if not subfonts then
-      return getinfo(fontdata,nil,platformnames,rawfamilynames)
-    elseif not subfont then
-      local info={}
-      for i=1,#subfonts do
-        info[i]=getinfo(fontdata,i,platformnames,rawfamilynames)
-      end
-      return info
-    elseif subfont>=1 and subfont<=#subfonts then
-      return getinfo(fontdata,subfont,platformnames,rawfamilynames)
-    else
-      return {
-        filename=filename,
-        comment="there is no subfont "..subfont.." in this file"
-      }
-    end
-  else
-    return {
-      filename=filename,
-      comment="the file cannot be opened for reading",
-    }
-  end
-end
-function readers.rehash(fontdata,hashmethod)
-  report("the %a helper is not yet implemented","rehash")
-end
-function readers.checkhash(fontdata)
-  report("the %a helper is not yet implemented","checkhash")
-end
-function readers.pack(fontdata,hashmethod)
-  report("the %a helper is not yet implemented","pack")
-end
-function readers.unpack(fontdata)
-  report("the %a helper is not yet implemented","unpack")
-end
-function readers.expand(fontdata)
-  report("the %a helper is not yet implemented","unpack")
-end
-function readers.compact(fontdata)
-  report("the %a helper is not yet implemented","compact")
-end
-local extenders={}
-function readers.registerextender(extender)
-  extenders[#extenders+1]=extender
-end
-function readers.extend(fontdata)
-  for i=1,#extenders do
-    local extender=extenders[i]
-    local name=extender.name or "unknown"
-    local action=extender.action
-    if action then
-      action(fontdata)
-    end
-  end
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-otr”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-cff” f3fc74e8629f7a2825c34a34550c790d] ---
-
-if not modules then modules={} end modules ['font-cff']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local next,type,tonumber=next,type,tonumber
-local byte=string.byte
-local concat,remove=table.concat,table.remove
-local floor,abs,round,ceil=math.floor,math.abs,math.round,math.ceil
-local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct
-local lpegmatch=lpeg.match
-local formatters=string.formatters
-local readers=fonts.handlers.otf.readers
-local streamreader=readers.streamreader
-local readbytes=streamreader.readbytes
-local readstring=streamreader.readstring
-local readbyte=streamreader.readcardinal1 
-local readushort=streamreader.readcardinal2 
-local readuint=streamreader.readcardinal3 
-local readulong=streamreader.readcardinal4 
-local setposition=streamreader.setposition
-local getposition=streamreader.getposition
-local setmetatableindex=table.setmetatableindex
-local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end)
-local report=logs.reporter("otf reader","cff")
-local parsedictionaries
-local parsecharstring
-local parsecharstrings
-local resetcharstrings
-local parseprivates
-local defaultstrings={ [0]=
-  ".notdef","space","exclam","quotedbl","numbersign","dollar","percent",
-  "ampersand","quoteright","parenleft","parenright","asterisk","plus",
-  "comma","hyphen","period","slash","zero","one","two","three","four",
-  "five","six","seven","eight","nine","colon","semicolon","less",
-  "equal","greater","question","at","A","B","C","D","E","F","G","H",
-  "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W",
-  "X","Y","Z","bracketleft","backslash","bracketright","asciicircum",
-  "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j",
-  "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y",
-  "z","braceleft","bar","braceright","asciitilde","exclamdown","cent",
-  "sterling","fraction","yen","florin","section","currency",
-  "quotesingle","quotedblleft","guillemotleft","guilsinglleft",
-  "guilsinglright","fi","fl","endash","dagger","daggerdbl",
-  "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase",
-  "quotedblright","guillemotright","ellipsis","perthousand","questiondown",
-  "grave","acute","circumflex","tilde","macron","breve","dotaccent",
-  "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash",
-  "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae",
-  "dotlessi","lslash","oslash","oe","germandbls","onesuperior",
-  "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn",
-  "onequarter","divide","brokenbar","degree","thorn","threequarters",
-  "twosuperior","registered","minus","eth","multiply","threesuperior",
-  "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring",
-  "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave",
-  "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute",
-  "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute",
-  "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron",
-  "aacute","acircumflex","adieresis","agrave","aring","atilde",
-  "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute",
-  "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex",
-  "odieresis","ograve","otilde","scaron","uacute","ucircumflex",
-  "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall",
-  "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall",
-  "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader",
-  "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle",
-  "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle",
-  "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior",
-  "threequartersemdash","periodsuperior","questionsmall","asuperior",
-  "bsuperior","centsuperior","dsuperior","esuperior","isuperior",
-  "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior",
-  "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior",
-  "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall",
-  "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall",
-  "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall",
-  "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall",
-  "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah",
-  "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall",
-  "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall",
-  "Dotaccentsmall","Macronsmall","figuredash","hypheninferior",
-  "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth",
-  "threeeighths","fiveeighths","seveneighths","onethird","twothirds",
-  "zerosuperior","foursuperior","fivesuperior","sixsuperior",
-  "sevensuperior","eightsuperior","ninesuperior","zeroinferior",
-  "oneinferior","twoinferior","threeinferior","fourinferior",
-  "fiveinferior","sixinferior","seveninferior","eightinferior",
-  "nineinferior","centinferior","dollarinferior","periodinferior",
-  "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall",
-  "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall",
-  "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall",
-  "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall",
-  "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall",
-  "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall",
-  "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall",
-  "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003",
-  "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold",
-}
-local cffreaders={
-  readbyte,
-  readushort,
-  readuint,
-  readulong,
-}
-local function readheader(f)
-  local offset=getposition(f)
-  local header={
-    offset=offset,
-    major=readbyte(f),
-    minor=readbyte(f),
-    size=readbyte(f),
-    osize=readbyte(f),
-  }
-  setposition(f,offset+header.size)
-  return header
-end
-local function readlengths(f)
-  local count=readushort(f)
-  if count==0 then
-    return {}
-  end
-  local osize=readbyte(f)
-  local read=cffreaders[osize]
-  if not read then
-    report("bad offset size: %i",osize)
-    return {}
-  end
-  local lengths={}
-  local previous=read(f)
-  for i=1,count do
-    local offset=read(f)
-    lengths[i]=offset-previous
-    previous=offset
-  end
-  return lengths
-end
-local function readfontnames(f)
-  local names=readlengths(f)
-  for i=1,#names do
-    names[i]=readstring(f,names[i])
-  end
-  return names
-end
-local function readtopdictionaries(f)
-  local dictionaries=readlengths(f)
-  for i=1,#dictionaries do
-    dictionaries[i]=readstring(f,dictionaries[i])
-  end
-  return dictionaries
-end
-local function readstrings(f)
-  local lengths=readlengths(f)
-  local strings=setmetatableindex({},defaultstrings)
-  local index=#defaultstrings
-  for i=1,#lengths do
-    index=index+1
-    strings[index]=readstring(f,lengths[i])
-  end
-  return strings
-end
-do
-  local stack={}
-  local top=0
-  local result={}
-  local strings={}
-  local p_single=P("\00")/function()
-      result.version=strings[stack[top]] or "unset"
-      top=0
-    end+P("\01")/function()
-      result.notice=strings[stack[top]] or "unset"
-      top=0
-    end+P("\02")/function()
-      result.fullname=strings[stack[top]] or "unset"
-      top=0
-    end+P("\03")/function()
-      result.familyname=strings[stack[top]] or "unset"
-      top=0
-    end+P("\04")/function()
-      result.weight=strings[stack[top]] or "unset"
-      top=0
-    end+P("\05")/function()
-      result.fontbbox={ unpack(stack,1,4) }
-      top=0
-    end
-+P("\13")/function()
-      result.uniqueid=stack[top]
-      top=0
-    end+P("\14")/function()
-      result.xuid=concat(stack,"",1,top)
-      top=0
-    end+P("\15")/function()
-      result.charset=stack[top]
-      top=0
-    end+P("\16")/function()
-      result.encoding=stack[top]
-      top=0
-    end+P("\17")/function()
-      result.charstrings=stack[top]
-      top=0
-    end+P("\18")/function()
-      result.private={
-        size=stack[top-1],
-        offset=stack[top],
-      }
-      top=0
-    end+P("\19")/function()
-      result.subroutines=stack[top]
-    end+P("\20")/function()
-      result.defaultwidthx=stack[top]
-    end+P("\21")/function()
-      result.nominalwidthx=stack[top]
-    end
-  local p_double=P("\12")*(
-    P("\00")/function()
-      result.copyright=stack[top]
-      top=0
-    end+P("\01")/function()
-      result.monospaced=stack[top]==1 and true or false 
-      top=0
-    end+P("\02")/function()
-      result.italicangle=stack[top]
-      top=0
-    end+P("\03")/function()
-      result.underlineposition=stack[top]
-      top=0
-    end+P("\04")/function()
-      result.underlinethickness=stack[top]
-      top=0
-    end+P("\05")/function()
-      result.painttype=stack[top]
-      top=0
-    end+P("\06")/function()
-      result.charstringtype=stack[top]
-      top=0
-    end+P("\07")/function()
-      result.fontmatrix={ unpack(stack,1,6) }
-      top=0
-    end+P("\08")/function()
-      result.strokewidth=stack[top]
-      top=0
-    end+P("\20")/function()
-      result.syntheticbase=stack[top]
-      top=0
-    end+P("\21")/function()
-      result.postscript=strings[stack[top]] or "unset"
-      top=0
-    end+P("\22")/function()
-      result.basefontname=strings[stack[top]] or "unset"
-      top=0
-    end+P("\21")/function()
-      result.basefontblend=stack[top]
-      top=0
-    end+P("\30")/function()
-      result.cid.registry=strings[stack[top-2]] or "unset"
-      result.cid.ordering=strings[stack[top-1]] or "unset"
-      result.cid.supplement=stack[top]
-      top=0
-    end+P("\31")/function()
-      result.cid.fontversion=stack[top]
-      top=0
-    end+P("\32")/function()
-      result.cid.fontrevision=stack[top]
-      top=0
-    end+P("\33")/function()
-      result.cid.fonttype=stack[top]
-      top=0
-    end+P("\34")/function()
-      result.cid.count=stack[top]
-      top=0
-    end+P("\35")/function()
-      result.cid.uidbase=stack[top]
-      top=0
-    end+P("\36")/function()
-      result.cid.fdarray=stack[top]
-      top=0
-    end+P("\37")/function()
-      result.cid.fdselect=stack[top]
-      top=0
-    end+P("\38")/function()
-      result.cid.fontname=strings[stack[top]] or "unset"
-      top=0
-    end
-  )
-  local p_last=P("\x0F")/"0"+P("\x1F")/"1"+P("\x2F")/"2"+P("\x3F")/"3"+P("\x4F")/"4"+P("\x5F")/"5"+P("\x6F")/"6"+P("\x7F")/"7"+P("\x8F")/"8"+P("\x9F")/"9"+P("\xAF")/""+P("\xBF")/""+P("\xCF")/""+P("\xDF")/""+P("\xEF")/""+R("\xF0\xFF")/""
-  local remap={
-    ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0",
-    ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="0.",["\x1B"]="0E",["\x1C"]="0E-",["\x1D"]="0",["\x1E"]="0-",["\x1F"]="0",
-    ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="0.",["\x2B"]="0E",["\x2C"]="0E-",["\x2D"]="0",["\x2E"]="0-",["\x2F"]="0",
-    ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="0.",["\x3B"]="0E",["\x3C"]="0E-",["\x3D"]="0",["\x3E"]="0-",["\x3F"]="0",
-    ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="0.",["\x4B"]="0E",["\x4C"]="0E-",["\x4D"]="0",["\x4E"]="0-",["\x4F"]="0",
-    ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="0.",["\x5B"]="0E",["\x5C"]="0E-",["\x5D"]="0",["\x5E"]="0-",["\x5F"]="0",
-    ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="0.",["\x6B"]="0E",["\x6C"]="0E-",["\x6D"]="0",["\x6E"]="0-",["\x6F"]="0",
-    ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="0.",["\x7B"]="0E",["\x7C"]="0E-",["\x7D"]="0",["\x7E"]="0-",["\x7F"]="0",
-    ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="0.",["\x8B"]="0E",["\x8C"]="0E-",["\x8D"]="0",["\x8E"]="0-",["\x8F"]="0",
-    ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="0.",["\x9B"]="0E",["\x9C"]="0E-",["\x9D"]="0",["\x9E"]="0-",["\x9F"]="0",
-    ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".",
-    ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E",
-    ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-",
-    ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-",
-  }
-  local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0+p_last)/function(n)
-    top=top+1
-    stack[top]=tonumber(n) or 0
-  end
-  local p_byte=C(R("\32\246"))/function(b0)
-    top=top+1
-    stack[top]=byte(b0)-139
-  end
-  local p_positive=C(R("\247\250"))*C(1)/function(b0,b1)
-    top=top+1
-    stack[top]=(byte(b0)-247)*256+byte(b1)+108
-  end
-  local p_negative=C(R("\251\254"))*C(1)/function(b0,b1)
-    top=top+1
-    stack[top]=-(byte(b0)-251)*256-byte(b1)-108
-  end
-  local p_short=P("\28")*C(1)*C(1)/function(b1,b2)
-    top=top+1
-    local n=0x100*byte(b1)+byte(b2)
-    if n>=0x8000 then
-      stack[top]=n-0xFFFF-1
-    else
-      stack[top]=n
-    end
-  end
-  local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4)
-    top=top+1
-    local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4)
-    if n>=0x8000000 then
-      stack[top]=n-0xFFFFFFFF-1
-    else
-      stack[top]=n
-    end
-  end
-  local p_unsupported=P(1)/function(detail)
-    top=0
-  end
-  local p_dictionary=(
-    p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported
-  )^1
-  parsedictionaries=function(data,dictionaries)
-    stack={}
-    strings=data.strings
-    for i=1,#dictionaries do
-      top=0
-      result={
-        monospaced=false,
-        italicangle=0,
-        underlineposition=-100,
-        underlinethickness=50,
-        painttype=0,
-        charstringtype=2,
-        fontmatrix={ 0.001,0,0,0.001,0,0 },
-        fontbbox={ 0,0,0,0 },
-        strokewidth=0,
-        charset=0,
-        encoding=0,
-        cid={
-          fontversion=0,
-          fontrevision=0,
-          fonttype=0,
-          count=8720,
-        }
-      }
-      lpegmatch(p_dictionary,dictionaries[i])
-      dictionaries[i]=result
-    end
-    result={}
-    top=0
-    stack={}
-  end
-  parseprivates=function(data,dictionaries)
-    stack={}
-    strings=data.strings
-    for i=1,#dictionaries do
-      local private=dictionaries[i].private
-      if private and private.data then
-        top=0
-        result={
-          forcebold=false,
-          languagegroup=0,
-          expansionfactor=0.06,
-          initialrandomseed=0,
-          subroutines=0,
-          defaultwidthx=0,
-          nominalwidthx=0,
-          cid={
-          },
-        }
-        lpegmatch(p_dictionary,private.data)
-        private.data=result
-      end
-    end
-    result={}
-    top=0
-    stack={}
-  end
-  local x=0
-  local y=0
-  local width=false
-  local r=0
-  local stems=0
-  local globalbias=0
-  local localbias=0
-  local globals=false
-  local locals=false
-  local depth=1
-  local xmin=0
-  local xmax=0
-  local ymin=0
-  local ymax=0
-  local checked=false
-  local keepcurve=false
-  local version=2
-  local function showstate(where)
-    report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top)
-  end
-  local function showvalue(where,value,showstack)
-    if showstack then
-      report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top)
-    else
-      report("%w%-10s : %s",depth*2,where,tostring(value))
-    end
-  end
-  local function moveto(x,y)
-    if keepcurve then
-      r=r+1
-      result[r]={ x,y,"m" }
-    end
-    if checked then
-      if x<xmin then xmin=x elseif x>xmax then xmax=x end
-      if y<ymin then ymin=y elseif y>ymax then ymax=y end
-    else
-      xmin=x
-      ymin=y
-      xmax=x
-      ymax=y
-      checked=true
-    end
-  end
-  local function lineto(x,y)
-    if keepcurve then
-      r=r+1
-      result[r]={ x,y,"l" }
-    end
-    if checked then
-      if x<xmin then xmin=x elseif x>xmax then xmax=x end
-      if y<ymin then ymin=y elseif y>ymax then ymax=y end
-    else
-      xmin=x
-      ymin=y
-      xmax=x
-      ymax=y
-      checked=true
-    end
-  end
-  local function curveto(x1,y1,x2,y2,x3,y3)
-    if keepcurve then
-      r=r+1
-      result[r]={ x1,y1,x2,y2,x3,y3,"c" }
-    end
-    if checked then
-      if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
-      if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
-    else
-      xmin=x1
-      ymin=y1
-      xmax=x1
-      ymax=y1
-      checked=true
-    end
-    if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
-    if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
-    if x3<xmin then xmin=x3 elseif x3>xmax then xmax=x3 end
-    if y3<ymin then ymin=y3 elseif y3>ymax then ymax=y3 end
-  end
-  local function rmoveto()
-    if top>2 then
-      if not width then
-        width=stack[1]
-        if trace_charstrings then
-          showvalue("width",width)
-        end
-      end
-    elseif not width then
-      width=true
-    end
-    if trace_charstrings then
-      showstate("rmoveto")
-    end
-    x=x+stack[top-1] 
-    y=y+stack[top]  
-    top=0
-    moveto(x,y)
-  end
-  local function hmoveto()
-    if top>1 then
-      if not width then
-        width=stack[1]
-        if trace_charstrings then
-          showvalue("width",width)
-        end
-      end
-    elseif not width then
-      width=true
-    end
-    if trace_charstrings then
-      showstate("hmoveto")
-    end
-    x=x+stack[top] 
-    top=0
-    moveto(x,y)
-  end
-  local function vmoveto()
-    if top>1 then
-      if not width then
-        width=stack[1]
-        if trace_charstrings then
-          showvalue("width",width)
-        end
-      end
-    elseif not width then
-      width=true
-    end
-    if trace_charstrings then
-      showstate("vmoveto")
-    end
-    y=y+stack[top] 
-    top=0
-    moveto(x,y)
-  end
-  local function rlineto()
-    if trace_charstrings then
-      showstate("rlineto")
-    end
-    for i=1,top,2 do
-      x=x+stack[i]  
-      y=y+stack[i+1] 
-      lineto(x,y)
-    end
-    top=0
-  end
-  local function xlineto(swap) 
-    for i=1,top do
-      if swap then
-        x=x+stack[i]
-        swap=false
-      else
-        y=y+stack[i]
-        swap=true
-      end
-      lineto(x,y)
-    end
-    top=0
-  end
-  local function hlineto() 
-    if trace_charstrings then
-      showstate("hlineto")
-    end
-    xlineto(true)
-  end
-  local function vlineto() 
-    if trace_charstrings then
-      showstate("vlineto")
-    end
-    xlineto(false)
-  end
-  local function rrcurveto()
-    if trace_charstrings then
-      showstate("rrcurveto")
-    end
-    for i=1,top,6 do
-      local ax=x+stack[i]  
-      local ay=y+stack[i+1] 
-      local bx=ax+stack[i+2] 
-      local by=ay+stack[i+3] 
-      x=bx+stack[i+4] 
-      y=by+stack[i+5] 
-      curveto(ax,ay,bx,by,x,y)
-    end
-    top=0
-  end
-  local function hhcurveto()
-    if trace_charstrings then
-      showstate("hhcurveto")
-    end
-    local s=1
-    if top%2~=0 then
-      y=y+stack[1] 
-      s=2
-    end
-    for i=s,top,4 do
-      local ax=x+stack[i] 
-      local ay=y
-      local bx=ax+stack[i+1] 
-      local by=ay+stack[i+2] 
-      x=bx+stack[i+3] 
-      y=by
-      curveto(ax,ay,bx,by,x,y)
-    end
-    top=0
-  end
-  local function vvcurveto()
-    if trace_charstrings then
-      showstate("vvcurveto")
-    end
-    local s=1
-    local d=0
-    if top%2~=0 then
-      d=stack[1] 
-      s=2
-    end
-    for i=s,top,4 do
-      local ax=x+d
-      local ay=y+stack[i] 
-      local bx=ax+stack[i+1] 
-      local by=ay+stack[i+2] 
-      x=bx
-      y=by+stack[i+3] 
-      curveto(ax,ay,bx,by,x,y)
-      d=0
-    end
-    top=0
-  end
-  local function xxcurveto(swap)
-    local last=top%4~=0 and stack[top]
-    if last then
-      top=top-1
-    end
-    local sw=swap
-    for i=1,top,4 do
-      local ax,ay,bx,by
-      if swap then
-        ax=x+stack[i]
-        ay=y
-        bx=ax+stack[i+1]
-        by=ay+stack[i+2]
-        y=by+stack[i+3]
-        if last and i+3==top then
-          x=bx+last
-        else
-          x=bx
-        end
-        swap=false
-      else
-        ax=x
-        ay=y+stack[i]
-        bx=ax+stack[i+1]
-        by=ay+stack[i+2]
-        x=bx+stack[i+3]
-        if last and i+3==top then
-          y=by+last
-        else
-          y=by
-        end
-        swap=true
-      end
-      curveto(ax,ay,bx,by,x,y)
-    end
-    top=0
-  end
-  local function hvcurveto()
-    if trace_charstrings then
-      showstate("hvcurveto")
-    end
-    xxcurveto(true)
-  end
-  local function vhcurveto()
-    if trace_charstrings then
-      showstate("vhcurveto")
-    end
-    xxcurveto(false)
-  end
-  local function rcurveline()
-    if trace_charstrings then
-      showstate("rcurveline")
-    end
-    for i=1,top-2,6 do
-      local ax=x+stack[i]  
-      local ay=y+stack[i+1] 
-      local bx=ax+stack[i+2] 
-      local by=ay+stack[i+3] 
-      x=bx+stack[i+4] 
-      y=by+stack[i+5] 
-      curveto(ax,ay,bx,by,x,y)
-    end
-    x=x+stack[top-1] 
-    y=y+stack[top]  
-    lineto(x,y)
-    top=0
-  end
-  local function rlinecurve()
-    if trace_charstrings then
-      showstate("rlinecurve")
-    end
-    if top>6 then
-      for i=1,top-6,2 do
-        x=x+stack[i]
-        y=y+stack[i+1]
-        lineto(x,y)
-      end
-    end
-    local ax=x+stack[top-5]
-    local ay=y+stack[top-4]
-    local bx=ax+stack[top-3]
-    local by=ay+stack[top-2]
-    x=bx+stack[top-1]
-    y=by+stack[top]
-    curveto(ax,ay,bx,by,x,y)
-    top=0
-  end
-  local function flex() 
-    if trace_charstrings then
-      showstate("flex")
-    end
-    local ax=x+stack[1] 
-    local ay=y+stack[2] 
-    local bx=ax+stack[3] 
-    local by=ay+stack[4] 
-    local cx=bx+stack[5] 
-    local cy=by+stack[6] 
-    curveto(ax,ay,bx,by,cx,cy)
-    local dx=cx+stack[7] 
-    local dy=cy+stack[8] 
-    local ex=dx+stack[9] 
-    local ey=dy+stack[10] 
-    x=ex+stack[11]    
-    y=ey+stack[12]    
-    curveto(dx,dy,ex,ey,x,y)
-    top=0
-  end
-  local function hflex()
-    if trace_charstrings then
-      showstate("hflex")
-    end
-    local ax=x+stack[1]  
-    local ay=y
-    local bx=ax+stack[2] 
-    local by=ay+stack[3] 
-    local cx=bx+stack[4] 
-    local cy=by
-    curveto(ax,ay,bx,by,cx,cy)
-    local dx=cx+stack[5] 
-    local dy=by
-    local ex=dx+stack[6] 
-    local ey=y
-    x=ex+stack[7]    
-    curveto(dx,dy,ex,ey,x,y)
-    top=0
-  end
-  local function hflex1()
-    if trace_charstrings then
-      showstate("hflex1")
-    end
-    local ax=x+stack[1] 
-    local ay=y+stack[2] 
-    local bx=ax+stack[3] 
-    local by=ay+stack[4] 
-    local cx=bx+stack[5] 
-    local cy=by
-    curveto(ax,ay,bx,by,cx,cy)
-    local dx=cx+stack[6] 
-    local dy=by
-    local ex=dx+stack[7] 
-    local ey=dy+stack[8] 
-    x=ex+stack[9]    
-    curveto(dx,dy,ex,ey,x,y)
-    top=0
-  end
-  local function flex1()
-    if trace_charstrings then
-      showstate("flex1")
-    end
-    local ax=x+stack[1] 
-    local ay=y+stack[2] 
-    local bx=ax+stack[3] 
-    local by=ay+stack[4] 
-    local cx=bx+stack[5] 
-    local cy=by+stack[6] 
-    curveto(ax,ay,bx,by,cx,cy)
-    local dx=cx+stack[7] 
-    local dy=cy+stack[8] 
-    local ex=dx+stack[9] 
-    local ey=dy+stack[10] 
-    if abs(ex-x)>abs(ey-y) then 
-      x=ex+stack[11]
-    else
-      y=ey+stack[11]
-    end
-    curveto(dx,dy,ex,ey,x,y)
-    top=0
-  end
-  local function getstem()
-    if top==0 then
-    elseif top%2~=0 then
-      if width then
-        remove(stack,1)
-      else
-        width=remove(stack,1)
-        if trace_charstrings then
-          showvalue("width",width)
-        end
-      end
-      top=top-1
-    end
-    if trace_charstrings then
-      showstate("stem")
-    end
-    stems=stems+top/2
-    top=0
-  end
-  local function getmask()
-    if top==0 then
-    elseif top%2~=0 then
-      if width then
-        remove(stack,1)
-      else
-        width=remove(stack,1)
-        if trace_charstrings then
-          showvalue("width",width)
-        end
-      end
-      top=top-1
-    end
-    if trace_charstrings then
-      showstate(operator==19 and "hintmark" or "cntrmask")
-    end
-    stems=stems+top/2
-    top=0
-    if stems==0 then
-    elseif stems<=8 then
-      return 1
-    else
-      return floor((stems+7)/8)
-    end
-  end
-  local function unsupported(t)
-    if trace_charstrings then
-      showstate("unsupported "..t)
-    end
-    top=0
-  end
-  local function unsupportedsub(t)
-    if trace_charstrings then
-      showstate("unsupported sub "..t)
-    end
-    top=0
-  end
-  local function getstem3()
-    if trace_charstrings then
-      showstate("stem3")
-    end
-    top=0
-  end
-  local function divide()
-    if version==1 then
-      local d=stack[top]
-      top=top-1
-      stack[top]=stack[top]/d
-    end
-  end
-  local function closepath()
-    if version==1 then
-      if trace_charstrings then
-        showstate("closepath")
-      end
-    end
-    top=0
-  end
-  local function hsbw()
-    if version==1 then
-      if trace_charstrings then
-        showstate("dotsection")
-      end
-      width=stack[top]
-    end
-    top=0
-  end
-  local function seac()
-    if version==1 then
-      if trace_charstrings then
-        showstate("seac")
-      end
-    end
-    top=0
-  end
-  local function sbw()
-    if version==1 then
-      if trace_charstrings then
-        showstate("sbw")
-      end
-      width=stack[top-1]
-    end
-    top=0
-  end
-  local function callothersubr()
-    if version==1 then
-      if trace_charstrings then
-        showstate("callothersubr (unsupported)")
-      end
-    end
-    top=0
-  end
-  local function pop()
-    if version==1 then
-      if trace_charstrings then
-        showstate("pop (unsupported)")
-      end
-      top=top+1
-      stack[top]=0 
-    else
-      top=0
-    end
-  end
-  local function setcurrentpoint()
-    if version==1 then
-      if trace_charstrings then
-        showstate("pop (unsupported)")
-      end
-      x=x+stack[top-1]
-      y=y+stack[top]
-    end
-    top=0
-  end
-  local actions={ [0]=unsupported,
-    getstem,
-    unsupported,
-    getstem,
-    vmoveto,
-    rlineto,
-    hlineto,
-    vlineto,
-    rrcurveto,
-    unsupported,
-    unsupported,
-    unsupported,
-    unsupported,
-    hsbw,
-    unsupported,
-    unsupported,
-    unsupported,
-    unsupported,
-    getstem,
-    getmask,
-    getmask,
-    rmoveto,
-    hmoveto,
-    getstem,
-    rcurveline,
-    rlinecurve,
-    vvcurveto,
-    hhcurveto,
-    unsupported,
-    unsupported,
-    vhcurveto,
-    hvcurveto,
-  }
-  local subactions={
-    [000]=dotsection,
-    [001]=getstem3,
-    [002]=getstem3,
-    [006]=seac,
-    [007]=sbw,
-    [012]=divide,
-    [016]=callothersubr,
-    [017]=pop,
-    [033]=setcurrentpoint,
-    [034]=hflex,
-    [035]=flex,
-    [036]=hflex1,
-    [037]=flex1,
-  }
-  local p_bytes=Ct((P(1)/byte)^0)
-  local function call(scope,list,bias,process)
-    depth=depth+1
-    if top==0 then
-      showstate(formatters["unknown %s call"](scope))
-      top=0
-    else
-      local index=stack[top]+bias
-      top=top-1
-      if trace_charstrings then
-        showvalue(scope,index,true)
-      end
-      local tab=list[index]
-      if tab then
-        if type(tab)=="string" then
-          tab=lpegmatch(p_bytes,tab)
-          list[index]=tab
-        end
-        process(tab)
-      else
-        showstate(formatters["unknown %s call %i"](scope,index))
-        top=0
-      end
-    end
-    depth=depth-1
-  end
-  local function process(tab)
-    local i=1
-    local n=#tab
-    while i<=n do
-      local t=tab[i]
-      if t>=32 and t<=246 then
-        top=top+1
-        stack[top]=t-139
-        i=i+1
-      elseif t>=247 and t<=250 then
-        top=top+1
-        stack[top]=(t-247)*256+tab[i+1]+108
-        i=i+2
-      elseif t>=251 and t<=254 then
-        top=top+1
-        stack[top]=-(t-251)*256-tab[i+1]-108
-        i=i+2
-      elseif t==28 then
-        top=top+1
-        local n=0x100*tab[i+1]+tab[i+2]
-        if n>=0x8000 then
-          stack[top]=n-0xFFFF-1
-        else
-          stack[top]=n
-        end
-        i=i+3
-      elseif t==255 then
-        local n=0x100*tab[i+1]+tab[i+2]
-        top=top+1
-        if n>=0x8000 then
-          stack[top]=n-0xFFFF-1+(0x100*tab[i+3]+tab[i+4])/0xFFFF
-        else
-          stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF
-        end
-        i=i+5
-      elseif t==11 then
-        if trace_charstrings then
-          showstate("return")
-        end
-        return
-      elseif t==10 then
-        call("local",locals,localbias,process)
-        i=i+1
-       elseif t==14 then 
-        if width then
-        elseif top>0 then
-          width=stack[1]
-          if trace_charstrings then
-            showvalue("width",width)
-          end
-        else
-          width=true
-        end
-        if trace_charstrings then
-          showstate("endchar")
-        end
-        return
-      elseif t==29 then
-        call("global",globals,globalbias,process)
-        i=i+1
-      elseif t==12 then
-        i=i+1
-        local t=tab[i]
-        local a=subactions[t]
-        if a then
-          a(t)
-        else
-          if trace_charstrings then
-            showvalue("<subaction>",t)
-          end
-          top=0
-        end
-        i=i+1
-      else
-        local a=actions[t]
-        if a then
-          local s=a(t)
-          if s then
-            i=i+s
-          end
-        else
-          if trace_charstrings then
-            showvalue("<action>",t)
-          end
-          top=0
-        end
-        i=i+1
-      end
-    end
-  end
-  local function setbias(globals,locals)
-    if version==1 then
-      return
-        false,
-        false
-    else
-      local g,l=#globals,#locals
-      return
-        ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1,
-        ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1
-    end
-  end
-  parsecharstrings=function(data,glyphs,doshapes,tversion)
-    local dictionary=data.dictionaries[1]
-    local charstrings=dictionary.charstrings
-    local charset=dictionary.charset
-    local private=dictionary.private or { data={} }
-    keepcurve=doshapes
-    version=tversion
-    stack={}
-    glyphs=glyphs or {}
-    strings=data.strings
-    globals=data.routines or {}
-    locals=dictionary.subroutines or {}
-    globalbias,localbias=setbias(globals,locals)
-    local nominalwidth=private.data.nominalwidthx or 0
-    local defaultwidth=private.data.defaultwidthx or 0
-    for i=1,#charstrings do
-      local tab=charstrings[i]
-      if type(tab)=="string" then
-        tab=lpegmatch(p_bytes,tab)
-      end
-      local index=i-1
-      x=0
-      y=0
-      width=false
-      r=0
-      top=0
-      stems=0
-      result={}
-      xmin=0
-      xmax=0
-      ymin=0
-      ymax=0
-      checked=false
-      if trace_charstrings then
-        report("glyph: %i",index)
-        report("data: % t",tab)
-      end
-      process(tab)
-      local boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) }
-      if width==true or width==false then
-        width=defaultwidth
-      else
-        width=nominalwidth+width
-      end
-      local glyph=glyphs[index] 
-      if not glyph then
-        glyphs[index]={
-          segments=doshapes~=false and result or nil,
-          boundingbox=boundingbox,
-          width=width,
-          name=charset[index],
-        }
-      else
-        glyph.segments=doshapes~=false and result or nil
-        glyph.boundingbox=boundingbox
-        if not glyph.width then
-          glyph.width=width
-        end
-        if charset and not glyph.name then
-          glyph.name=charset[index]
-        end
-      end
-      if trace_charstrings then
-        report("width: %s",tostring(width))
-        report("boundingbox: % t",boundingbox)
-      end
-      charstrings[i]=nil 
-    end
-    return glyphs
-  end
-  parsecharstring=function(data,dictionary,tab,glyphs,index,doshapes,tversion)
-    local private=dictionary.private
-    keepcurve=doshapes
-    version=tversion
-    strings=data.strings 
-    locals=dictionary.subroutines or {}
-    globals=data.routines or {}
-    globalbias,localbias=setbias(globals,locals)
-    local nominalwidth=private and private.data.nominalwidthx or 0
-    local defaultwidth=private and private.data.defaultwidthx or 0
-    if type(tab)=="string" then
-      tab=lpegmatch(p_bytes,tab)
-    end
-    x=0
-    y=0
-    width=false
-    r=0
-    top=0
-    stems=0
-    result={}
-    xmin=0
-    xmax=0
-    ymin=0
-    ymax=0
-    checked=false
-    if trace_charstrings then
-      report("glyph: %i",index)
-      report("data: % t",tab)
-    end
-    process(tab)
-    local boundingbox={ xmin,ymin,xmax,ymax }
-    if width==true or width==false then
-      width=defaultwidth
-    else
-      width=nominalwidth+width
-    end
-    index=index-1
-    local glyph=glyphs[index] 
-    if not glyph then
-      glyphs[index]={
-        segments=doshapes~=false and result or nil,
-        boundingbox=boundingbox,
-        width=width,
-        name=charset[index],
-      }
-    else
-      glyph.segments=doshapes~=false and result or nil
-      glyph.boundingbox=boundingbox
-      if not glyph.width then
-        glyph.width=width
-      end
-      if charset and not glyph.name then
-        glyph.name=charset[index]
-      end
-    end
-    if trace_charstrings then
-      report("width: %s",tostring(width))
-      report("boundingbox: % t",boundingbox)
-    end
-  end
-  resetcharstrings=function()
-    result={}
-    top=0
-    stack={}
-  end
-end
-local function readglobals(f,data)
-  local routines=readlengths(f)
-  for i=1,#routines do
-    routines[i]=readstring(f,routines[i])
-  end
-  data.routines=routines
-end
-local function readencodings(f,data)
-  data.encodings={}
-end
-local function readcharsets(f,data,dictionary)
-  local header=data.header
-  local strings=data.strings
-  local nofglyphs=data.nofglyphs
-  local charsetoffset=dictionary.charset
-  if charsetoffset~=0 then
-    setposition(f,header.offset+charsetoffset)
-    local format=readbyte(f)
-    local charset={ [0]=".notdef" }
-    dictionary.charset=charset
-    if format==0 then
-      for i=1,nofglyphs do
-        charset[i]=strings[readushort(f)]
-      end
-    elseif format==1 or format==2 then
-      local readcount=format==1 and readbyte or readushort
-      local i=1
-      while i<=nofglyphs do
-        local sid=readushort(f)
-        local n=readcount(f)
-        for s=sid,sid+n do
-          charset[i]=strings[s]
-          i=i+1
-          if i>nofglyphs then
-            break
-          end
-        end
-      end
-    else
-      report("cff parser: unsupported charset format %a",format)
-    end
-  end
-end
-local function readprivates(f,data)
-  local header=data.header
-  local dictionaries=data.dictionaries
-  local private=dictionaries[1].private
-  if private then
-    setposition(f,header.offset+private.offset)
-    private.data=readstring(f,private.size)
-  end
-end
-local function readlocals(f,data,dictionary)
-  local header=data.header
-  local private=dictionary.private
-  if private then
-    local subroutineoffset=private.data.subroutines
-    if subroutineoffset~=0 then
-      setposition(f,header.offset+private.offset+subroutineoffset)
-      local subroutines=readlengths(f)
-      for i=1,#subroutines do
-        subroutines[i]=readstring(f,subroutines[i])
-      end
-      dictionary.subroutines=subroutines
-      private.data.subroutines=nil
-    else
-      dictionary.subroutines={}
-    end
-  else
-    dictionary.subroutines={}
-  end
-end
-local function readcharstrings(f,data)
-  local header=data.header
-  local dictionaries=data.dictionaries
-  local dictionary=dictionaries[1]
-  local type=dictionary.charstringtype
-  local offset=dictionary.charstrings
-  if type==2 then
-    setposition(f,header.offset+offset)
-    local charstrings=readlengths(f)
-    local nofglyphs=#charstrings
-    for i=1,nofglyphs do
-      charstrings[i]=readstring(f,charstrings[i])
-    end
-    data.nofglyphs=nofglyphs
-    dictionary.charstrings=charstrings
-  else
-    report("unsupported charstr type %i",type)
-    data.nofglyphs=0
-    dictionary.charstrings={}
-  end
-end
-local function readcidprivates(f,data)
-  local header=data.header
-  local dictionaries=data.dictionaries[1].cid.dictionaries
-  for i=1,#dictionaries do
-    local dictionary=dictionaries[i]
-    local private=dictionary.private
-    if private then
-      setposition(f,header.offset+private.offset)
-      private.data=readstring(f,private.size)
-    end
-  end
-  parseprivates(data,dictionaries)
-end
-local function readnoselect(f,data,glyphs,doshapes,version)
-  local dictionaries=data.dictionaries
-  local dictionary=dictionaries[1]
-  readglobals(f,data)
-  readcharstrings(f,data)
-  readencodings(f,data)
-  readcharsets(f,data,dictionary)
-  readprivates(f,data)
-  parseprivates(data,data.dictionaries)
-  readlocals(f,data,dictionary)
-  parsecharstrings(data,glyphs,doshapes,version)
-  resetcharstrings()
-end
-readers.parsecharstrings=parsecharstrings
-local function readfdselect(f,data,glyphs,doshapes,version)
-  local header=data.header
-  local dictionaries=data.dictionaries
-  local dictionary=dictionaries[1]
-  local cid=dictionary.cid
-  local cidselect=cid and cid.fdselect
-  readglobals(f,data)
-  readcharstrings(f,data)
-  readencodings(f,data)
-  local charstrings=dictionary.charstrings
-  local fdindex={}
-  local nofglyphs=data.nofglyphs
-  local maxindex=-1
-  setposition(f,header.offset+cidselect)
-  local format=readbyte(f)
-  if format==1 then
-    for i=0,nofglyphs do 
-      local index=readbyte(i)
-      fdindex[i]=index
-      if index>maxindex then
-        maxindex=index
-      end
-    end
-  elseif format==3 then
-    local nofranges=readushort(f)
-    local first=readushort(f)
-    local index=readbyte(f)
-    while true do
-      local last=readushort(f)
-      if index>maxindex then
-        maxindex=index
-      end
-      for i=first,last do
-        fdindex[i]=index
-      end
-      if last>=nofglyphs then
-        break
-      else
-        first=last+1
-        index=readbyte(f)
-      end
-    end
-  else
-  end
-  if maxindex>=0 then
-    local cidarray=cid.fdarray
-    setposition(f,header.offset+cidarray)
-    local dictionaries=readlengths(f)
-    for i=1,#dictionaries do
-      dictionaries[i]=readstring(f,dictionaries[i])
-    end
-    parsedictionaries(data,dictionaries)
-    cid.dictionaries=dictionaries
-    readcidprivates(f,data)
-    for i=1,#dictionaries do
-      readlocals(f,data,dictionaries[i])
-    end
-    for i=1,#charstrings do
-      parsecharstring(data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version)
-    end
-    resetcharstrings()
-  end
-end
-function readers.cff(f,fontdata,specification)
-  if specification.details then
-    local datatable=fontdata.tables.cff
-    if datatable then
-      local offset=datatable.offset
-      local glyphs=fontdata.glyphs
-      if not f then
-        report("invalid filehandle")
-        return
-      end
-      if offset then
-        setposition(f,offset)
-      end
-      local header=readheader(f)
-      if header.major>1 then
-        report("version mismatch")
-        return
-      end
-      local names=readfontnames(f)
-      local dictionaries=readtopdictionaries(f)
-      local strings=readstrings(f)
-      local data={
-        header=header,
-        names=names,
-        dictionaries=dictionaries,
-        strings=strings,
-        nofglyphs=fontdata.nofglyphs,
-      }
-      parsedictionaries(data,data.dictionaries)
-      local d=dictionaries[1]
-      local c=d.cid
-      fontdata.cffinfo={
-        familynamename=d.familyname,
-        fullname=d.fullname,
-        boundingbox=d.boundingbox,
-        weight=d.weight,
-        italicangle=d.italicangle,
-        underlineposition=d.underlineposition,
-        underlinethickness=d.underlinethickness,
-        monospaced=d.monospaced,
-      }
-      fontdata.cidinfo=c and {
-        registry=c.registry,
-        ordering=c.ordering,
-        supplement=c.supplement,
-      }
-      if not specification.glyphs then
-      else
-        local cid=d.cid
-        if cid and cid.fdselect then
-          readfdselect(f,data,glyphs,specification.shapes or false)
-        else
-          readnoselect(f,data,glyphs,specification.shapes or false)
-        end
-      end
-    end
-  end
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-cff”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-ttf” e0893de6d0f3f421ee4386fa90429db8] ---
-
-if not modules then modules={} end modules ['font-ttf']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local next,type,unpack=next,type,unpack
-local bittest=bit32.btest
-local sqrt=math.sqrt
-local report=logs.reporter("otf reader","ttf")
-local readers=fonts.handlers.otf.readers
-local streamreader=readers.streamreader
-local setposition=streamreader.setposition
-local getposition=streamreader.getposition
-local skipbytes=streamreader.skip
-local readbyte=streamreader.readcardinal1 
-local readushort=streamreader.readcardinal2 
-local readulong=streamreader.readcardinal4 
-local readchar=streamreader.readinteger1  
-local readshort=streamreader.readinteger2  
-local read2dot14=streamreader.read2dot14   
-local function mergecomposites(glyphs,shapes)
-  local function merge(index,shape,components)
-    local contours={}
-    local nofcontours=0
-    for i=1,#components do
-      local component=components[i]
-      local subindex=component.index
-      local subshape=shapes[subindex]
-      local subcontours=subshape.contours
-      if not subcontours then
-        local subcomponents=subshape.components
-        if subcomponents then
-          subcontours=merge(subindex,subshape,subcomponents)
-        end
-      end
-      if subcontours then
-        local matrix=component.matrix
-        local xscale=matrix[1]
-        local xrotate=matrix[2]
-        local yrotate=matrix[3]
-        local yscale=matrix[4]
-        local xoffset=matrix[5]
-        local yoffset=matrix[6]
-        for i=1,#subcontours do
-          local points=subcontours[i]
-          local result={}
-          for i=1,#points do
-            local p=points[i]
-            local x=p[1]
-            local y=p[2]
-            result[i]={
-              xscale*x+xrotate*y+xoffset,
-              yscale*y+yrotate*x+yoffset,
-              p[3]
-            }
-          end
-          nofcontours=nofcontours+1
-          contours[nofcontours]=result
-        end
-      else
-        report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex)
-      end
-    end
-    shape.contours=contours
-    shape.components=nil
-    return contours
-  end
-  for index=1,#glyphs do
-    local shape=shapes[index]
-    local components=shape.components
-    if components then
-      merge(index,shape,components)
-    end
-  end
-end
-local function readnothing(f,nofcontours)
-  return {
-    type="nothing",
-  }
-end
-local function curveto(m_x,m_y,l_x,l_y,r_x,r_y) 
-  return {
-    l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y),
-    r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y),
-    r_x,r_y,"c" 
-  }
-end
-local function contours2outlines(glyphs,shapes)
-  local quadratic=true
-  for index=1,#glyphs do
-    local glyph=glyphs[index]
-    local shape=shapes[index]
-    local contours=shape.contours
-    if contours then
-      local nofcontours=#contours
-      local segments={}
-      local nofsegments=0
-      glyph.segments=segments
-      if nofcontours>0 then
-        for i=1,nofcontours do
-          local contour=contours[i]
-          local nofcontour=#contour
-          if nofcontour>0 then
-            local first_pt=contour[1]
-            local first_on=first_pt[3]
-            if nofcontour==1 then
-              first_pt[3]="m" 
-              nofsegments=nofsegments+1
-              segments[nofsegments]=first_pt
-            else 
-              local first_on=first_pt[3]
-              local last_pt=contour[nofcontour]
-              local last_on=last_pt[3]
-              local start=1
-              local control_pt=false
-              if first_on then
-                start=2
-              else
-                if last_on then
-                  first_pt=last_pt
-                else
-                  first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false }
-                end
-                control_pt=first_pt
-              end
-              nofsegments=nofsegments+1
-              segments[nofsegments]={ first_pt[1],first_pt[2],"m" } 
-              local previous_pt=first_pt
-              for i=start,nofcontour do
-                local current_pt=contour[i]
-                local current_on=current_pt[3]
-                local previous_on=previous_pt[3]
-                if previous_on then
-                  if current_on then
-                    nofsegments=nofsegments+1
-                    segments[nofsegments]={ current_pt[1],current_pt[2],"l" } 
-                  else
-                    control_pt=current_pt
-                  end
-                elseif current_on then
-                  local ps=segments[nofsegments]
-                  nofsegments=nofsegments+1
-                  if quadratic then
-                    segments[nofsegments]={ control_pt[1],control_pt[2],current_pt[1],current_pt[2],"q" } 
-                  else
-                    local p=segments[nofsegments-1] local n=#p
-                    segments[nofsegments]=curveto(control_pt[1],control_pt[2],p[n-2],p[n-1],current_pt[1],current_pt[2])
-                  end
-                  control_pt=false
-                else
-                  nofsegments=nofsegments+1
-                  local halfway_x=(previous_pt[1]+current_pt[1])/2
-                  local halfway_y=(previous_pt[2]+current_pt[2])/2
-                  if quadratic then
-                    segments[nofsegments]={ control_pt[1],control_pt[2],halfway_x,halfway_y,"q" } 
-                  else
-                    local p=segments[nofsegments-1] local n=#p
-                    segments[nofsegments]=curveto(control_pt[1],control_pt[2],p[n-2],p[n-1],halfway_x,halfway_y)
-                  end
-                  control_pt=current_pt
-                end
-                previous_pt=current_pt
-              end
-              if first_pt==last_pt then
-              else
-                nofsegments=nofsegments+1
-                if not control_pt then
-                  segments[nofsegments]={ first_pt[1],first_pt[2],"l" } 
-                elseif quadratic then
-                  segments[nofsegments]={ control_pt[1],control_pt[2],first_pt[1],first_pt[2],"q" } 
-                else
-                  local p=last_pt local n=#p
-                  segments[nofsegments]=curveto(control_pt[1],control_pt[2],p[n-2],p[n-1],first_pt[1],first_pt[2])
-                end
-              end
-            end
-          end
-        end
-      end
-    end
-  end
-end
-local function readglyph(f,nofcontours)
-  local points={}
-  local endpoints={}
-  local instructions={}
-  local flags={}
-  for i=1,nofcontours do
-    endpoints[i]=readshort(f)+1
-  end
-  local nofpoints=endpoints[nofcontours]
-  local nofinstructions=readushort(f)
-  skipbytes(f,nofinstructions)
-  local i=1
-  while i<=nofpoints do
-    local flag=readbyte(f)
-    flags[i]=flag
-    if bittest(flag,0x0008) then
-      for j=1,readbyte(f) do
-        i=i+1
-        flags[i]=flag
-      end
-    end
-    i=i+1
-  end
-  local x=0
-  for i=1,nofpoints do
-    local flag=flags[i]
-    local short=bittest(flag,0x0002)
-    local same=bittest(flag,0x0010)
-    if short then
-      if same then
-        x=x+readbyte(f)
-      else
-        x=x-readbyte(f)
-      end
-    elseif same then
-    else
-      x=x+readshort(f)
-    end
-    points[i]={ x,y,bittest(flag,0x0001) }
-  end
-  local y=0
-  for i=1,nofpoints do
-    local flag=flags[i]
-    local short=bittest(flag,0x0004)
-    local same=bittest(flag,0x0020)
-    if short then
-      if same then
-        y=y+readbyte(f)
-      else
-        y=y-readbyte(f)
-      end
-    elseif same then
-    else
-      y=y+readshort(f)
-    end
-    points[i][2]=y
-  end
-  local first=1
-  for i=1,#endpoints do
-    local last=endpoints[i]
-    endpoints[i]={ unpack(points,first,last) }
-    first=last+1
-  end
-  return {
-    type="glyph",
-    contours=endpoints,
-  }
-end
-local function readcomposite(f)
-  local components={}
-  local nofcomponents=0
-  local instructions=false
-  while true do
-    local flags=readushort(f)
-    local index=readushort(f)
-    local f_xyarg=bittest(flags,0x0002)
-    local f_offset=bittest(flags,0x0800)
-    local xscale=1
-    local xrotate=0
-    local yrotate=0
-    local yscale=1
-    local xoffset=0
-    local yoffset=0
-    local base=false
-    local reference=false
-    if f_xyarg then
-      if bittest(flags,0x0001) then 
-        xoffset=readshort(f)
-        yoffset=readshort(f)
-      else
-        xoffset=readchar(f) 
-        yoffset=readchar(f) 
-      end
-    else
-      if bittest(flags,0x0001) then 
-        base=readshort(f)
-        reference=readshort(f)
-      else
-        base=readchar(f) 
-        reference=readchar(f) 
-      end
-    end
-    if bittest(flags,0x0008) then 
-      xscale=read2dot14(f)
-      yscale=xscale
-      if f_xyarg and f_offset then
-        xoffset=xoffset*xscale
-        yoffset=yoffset*yscale
-      end
-    elseif bittest(flags,0x0040) then 
-      xscale=read2dot14(f)
-      yscale=read2dot14(f)
-      if f_xyarg and f_offset then
-        xoffset=xoffset*xscale
-        yoffset=yoffset*yscale
-      end
-    elseif bittest(flags,0x0080) then 
-      xscale=read2dot14(f)
-      xrotate=read2dot14(f)
-      yrotate=read2dot14(f)
-      yscale=read2dot14(f)
-      if f_xyarg and f_offset then
-        xoffset=xoffset*sqrt(xscale^2+xrotate^2)
-        yoffset=yoffset*sqrt(yrotate^2+yscale^2)
-      end
-    end
-    nofcomponents=nofcomponents+1
-    components[nofcomponents]={
-      index=index,
-      usemine=bittest(flags,0x0200),
-      round=bittest(flags,0x0006),
-      base=base,
-      reference=reference,
-      matrix={ xscale,xrotate,yrotate,yscale,xoffset,yoffset },
-    }
-    if bittest(flags,0x0100) then
-      instructions=true
-    end
-    if not bittest(flags,0x0020) then 
-      break
-    end
-  end
-  return {
-    type="composite",
-    components=components,
-  }
-end
-function readers.loca(f,fontdata,specification)
-  if specification.glyphs then
-    local datatable=fontdata.tables.loca
-    if datatable then
-      local offset=fontdata.tables.glyf.offset
-      local format=fontdata.fontheader.indextolocformat
-      local locations={}
-      setposition(f,datatable.offset)
-      if format==1 then
-        local nofglyphs=datatable.length/4-1
-      -1
-        for i=0,nofglyphs do
-          locations[i]=offset+readulong(f)
-        end
-        fontdata.nofglyphs=nofglyphs
-      else
-        local nofglyphs=datatable.length/2-1
-      -1
-        for i=0,nofglyphs do
-          locations[i]=offset+readushort(f)*2
-        end
-        fontdata.nofglyphs=nofglyphs
-      end
-      fontdata.locations=locations
-    end
-  end
-end
-function readers.glyf(f,fontdata,specification) 
-  if specification.glyphs then
-    local datatable=fontdata.tables.glyf
-    if datatable then
-      local locations=fontdata.locations
-      if locations then
-        local glyphs=fontdata.glyphs
-        local nofglyphs=fontdata.nofglyphs
-        local filesize=fontdata.filesize
-        local nothing={ 0,0,0,0 }
-        local shapes={}
-        local loadshapes=specification.shapes
-        for index=0,nofglyphs do
-          local location=locations[index]
-          if location>=filesize then
-            report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1)
-            fontdata.nofglyphs=index-1
-            fontdata.badfont=true
-            break
-          elseif location>0 then
-            setposition(f,location)
-            local nofcontours=readshort(f)
-            glyphs[index].boundingbox={
-              readshort(f),
-              readshort(f),
-              readshort(f),
-              readshort(f),
-            }
-            if not loadshapes then
-            elseif nofcontours==0 then
-              shapes[index]=readnothing(f,nofcontours)
-            elseif nofcontours>0 then
-              shapes[index]=readglyph(f,nofcontours)
-            else
-              shapes[index]=readcomposite(f,nofcontours)
-            end
-          else
-            if loadshapes then
-              shapes[index]={}
-            end
-            glyphs[index].boundingbox=nothing
-          end
-        end
-        if loadshapes then
-          mergecomposites(glyphs,shapes)
-          contours2outlines(glyphs,shapes)
-        end
-      end
-    end
-  end
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-ttf”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-dsp” 4a5266ada979d5c2d48867dc3ffaefea] ---
-
-if not modules then modules={} end modules ['font-dsp']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local next,type=next,type
-local bittest=bit32.btest
-local rshift=bit32.rshift
-local concat=table.concat
-local lower=string.lower
-local copy=table.copy
-local sub=string.sub
-local strip=string.strip
-local tohash=table.tohash
-local reversed=table.reversed
-local setmetatableindex=table.setmetatableindex
-local formatters=string.formatters
-local sortedkeys=table.sortedkeys
-local sortedhash=table.sortedhash
-local report=logs.reporter("otf reader")
-local readers=fonts.handlers.otf.readers
-local streamreader=readers.streamreader
-local setposition=streamreader.setposition
-local getposition=streamreader.getposition
-local skipshort=streamreader.skipshort
-local readushort=streamreader.readcardinal2 
-local readulong=streamreader.readcardinal4 
-local readshort=streamreader.readinteger2  
-local readfword=readshort
-local readstring=streamreader.readstring
-local readtag=streamreader.readtag
-local readbytes=streamreader.readbytes
-local gsubhandlers={}
-local gposhandlers={}
-local lookupidoffset=-1  
-local classes={
-  "base",
-  "ligature",
-  "mark",
-  "component",
-}
-local gsubtypes={
-  "single",
-  "multiple",
-  "alternate",
-  "ligature",
-  "context",
-  "chainedcontext",
-  "extension",
-  "reversechainedcontextsingle",
-}
-local gpostypes={
-  "single",
-  "pair",
-  "cursive",
-  "marktobase",
-  "marktoligature",
-  "marktomark",
-  "context",
-  "chainedcontext",
-  "extension",
-}
-local chaindirections={
-  context=0,
-  chainedcontext=1,
-  reversechainedcontextsingle=-1,
-}
-local lookupnames={
-  gsub={
-    single="gsub_single",
-    multiple="gsub_multiple",
-    alternate="gsub_alternate",
-    ligature="gsub_ligature",
-    context="gsub_context",
-    chainedcontext="gsub_contextchain",
-    reversechainedcontextsingle="gsub_reversecontextchain",
-  },
-  gpos={
-    single="gpos_single",
-    pair="gpos_pair",
-    cursive="gpos_cursive",
-    marktobase="gpos_mark2base",
-    marktoligature="gpos_mark2ligature",
-    marktomark="gpos_mark2mark",
-    context="gpos_context",
-    chainedcontext="gpos_contextchain",
-  }
-}
-local lookupflags=setmetatableindex(function(t,k)
-  local v={
-    bittest(k,0x0008) and true or false,
-    bittest(k,0x0004) and true or false,
-    bittest(k,0x0002) and true or false,
-    bittest(k,0x0001) and true or false,
-  }
-  t[k]=v
-  return v
-end)
-local function readcoverage(f,offset,simple)
-  setposition(f,offset)
-  local coverageformat=readushort(f)
-  local coverage={}
-  if coverageformat==1 then
-    local nofcoverage=readushort(f)
-    if simple then
-      for i=1,nofcoverage do
-        coverage[i]=readushort(f)
-      end
-    else
-      for i=0,nofcoverage-1 do
-        coverage[readushort(f)]=i 
-      end
-    end
-  elseif coverageformat==2 then
-    local nofranges=readushort(f)
-    local n=simple and 1 or 0 
-    for i=1,nofranges do
-      local firstindex=readushort(f)
-      local lastindex=readushort(f)
-      local coverindex=readushort(f)
-      if simple then
-        for i=firstindex,lastindex do
-          coverage[n]=i
-          n=n+1
-        end
-      else
-        for i=firstindex,lastindex do
-          coverage[i]=n
-          n=n+1
-        end
-      end
-    end
-  else
-    report("unknown coverage format %a ",coverageformat)
-  end
-  return coverage
-end
-local function readclassdef(f,offset,preset)
-  setposition(f,offset)
-  local classdefformat=readushort(f)
-  local classdef={}
-  if type(preset)=="number" then
-    for k=0,preset-1 do
-      classdef[k]=1
-    end
-  end
-  if classdefformat==1 then
-    local index=readushort(f)
-    local nofclassdef=readushort(f)
-    for i=1,nofclassdef do
-      classdef[index]=readushort(f)+1
-      index=index+1
-    end
-  elseif classdefformat==2 then
-    local nofranges=readushort(f)
-    local n=0
-    for i=1,nofranges do
-      local firstindex=readushort(f)
-      local lastindex=readushort(f)
-      local class=readushort(f)+1
-      for i=firstindex,lastindex do
-        classdef[i]=class
-      end
-    end
-  else
-    report("unknown classdef format %a ",classdefformat)
-  end
-  if type(preset)=="table" then
-    for k in next,preset do
-      if not classdef[k] then
-        classdef[k]=1
-      end
-    end
-  end
-  return classdef
-end
-local function classtocoverage(defs)
-  if defs then
-    local list={}
-    for index,class in next,defs do
-      local c=list[class]
-      if c then
-        c[#c+1]=index
-      else
-        list[class]={ index }
-      end
-    end
-    return list
-  end
-end
-local function readposition(f,format)
-  if format==0 then
-    return nil
-  end
-  local x=bittest(format,0x0001) and readshort(f) or 0 
-  local y=bittest(format,0x0002) and readshort(f) or 0 
-  local h=bittest(format,0x0004) and readshort(f) or 0 
-  local v=bittest(format,0x0008) and readshort(f) or 0 
-  if x==0 and y==0 and h==0 and v==0 then
-    return nil
-  else
-    return { x,y,h,v }
-  end
-end
-local function readanchor(f,offset)
-  if not offset or offset==0 then
-    return nil 
-  end
-  setposition(f,offset)
-  local format=readshort(f)
-  if format==0 then
-    report("invalid anchor format %i @ position %i",format,offset)
-    return false
-  elseif format>3 then
-    report("unsupported anchor format %i @ position %i",format,offset)
-    return false
-  end
-  return { readshort(f),readshort(f) }
-end
-local function readfirst(f,offset)
-  if offset then
-    setposition(f,offset)
-  end
-  return { readushort(f) }
-end
-local function readarray(f,offset,first)
-  if offset then
-    setposition(f,offset)
-  end
-  local n=readushort(f)
-  if first then
-    local t={ first }
-    for i=2,n do
-      t[i]=readushort(f)
-    end
-    return t,n
-  elseif n>0 then
-    local t={}
-    for i=1,n do
-      t[i]=readushort(f)
-    end
-    return t,n
-  end
-end
-local function readcoveragearray(f,offset,t,simple)
-  if not t then
-    return nil
-  end
-  local n=#t
-  if n==0 then
-    return nil
-  end
-  for i=1,n do
-    t[i]=readcoverage(f,offset+t[i],simple)
-  end
-  return t
-end
-local function covered(subset,all)
-  local used,u
-  for i=1,#subset do
-    local s=subset[i]
-    if all[s] then
-      if used then
-        u=u+1
-        used[u]=s
-      else
-        u=1
-        used={ s }
-      end
-    end
-  end
-  return used
-end
-local function readlookuparray(f,noflookups,nofcurrent)
-  local lookups={}
-  if noflookups>0 then
-    local length=0
-    for i=1,noflookups do
-      local index=readushort(f)+1
-      if index>length then
-        length=index
-      end
-      lookups[index]=readushort(f)+1
-    end
-    for index=1,length do
-      if not lookups[index] then
-        lookups[index]=false
-      end
-    end
-  end
-  return lookups
-end
-local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
-  local tableoffset=lookupoffset+offset
-  setposition(f,tableoffset)
-  local subtype=readushort(f)
-  if subtype==1 then
-    local coverage=readushort(f)
-    local subclasssets=readarray(f)
-    local rules={}
-    if subclasssets then
-      coverage=readcoverage(f,tableoffset+coverage,true)
-      for i=1,#subclasssets do
-        local offset=subclasssets[i]
-        if offset>0 then
-          local firstcoverage=coverage[i]
-          local rulesoffset=tableoffset+offset
-          local subclassrules=readarray(f,rulesoffset)
-          for rule=1,#subclassrules do
-            setposition(f,rulesoffset+subclassrules[rule])
-            local nofcurrent=readushort(f)
-            local noflookups=readushort(f)
-            local current={ { firstcoverage } }
-            for i=2,nofcurrent do
-              current[i]={ readushort(f) }
-            end
-            local lookups=readlookuparray(f,noflookups,nofcurrent)
-            rules[#rules+1]={
-              current=current,
-              lookups=lookups
-            }
-          end
-        end
-      end
-    else
-      report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
-    end
-    return {
-      format="glyphs",
-      rules=rules,
-    }
-  elseif subtype==2 then
-    local coverage=readushort(f)
-    local currentclassdef=readushort(f)
-    local subclasssets=readarray(f)
-    local rules={}
-    if subclasssets then
-      coverage=readcoverage(f,tableoffset+coverage)
-      currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage)
-      local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs)
-      for class=1,#subclasssets do
-        local offset=subclasssets[class]
-        if offset>0 then
-          local firstcoverage=currentclasses[class]
-          if firstcoverage then
-            firstcoverage=covered(firstcoverage,coverage) 
-            if firstcoverage then
-              local rulesoffset=tableoffset+offset
-              local subclassrules=readarray(f,rulesoffset)
-              for rule=1,#subclassrules do
-                setposition(f,rulesoffset+subclassrules[rule])
-                local nofcurrent=readushort(f)
-                local noflookups=readushort(f)
-                local current={ firstcoverage }
-                for i=2,nofcurrent do
-                  current[i]=currentclasses[readushort(f)+1]
-                end
-                local lookups=readlookuparray(f,noflookups,nofcurrent)
-                rules[#rules+1]={
-                  current=current,
-                  lookups=lookups
-                }
-              end
-            else
-              report("no coverage")
-            end
-          else
-            report("no coverage class")
-          end
-        end
-      end
-    else
-      report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
-    end
-    return {
-      format="class",
-      rules=rules,
-    }
-  elseif subtype==3 then
-    local current=readarray(f)
-    local noflookups=readushort(f)
-    local lookups=readlookuparray(f,noflookups,#current)
-    current=readcoveragearray(f,tableoffset,current,true)
-    return {
-      format="coverage",
-      rules={
-        {
-          current=current,
-          lookups=lookups,
-        }
-      }
-    }
-  else
-    report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what)
-  end
-end
-local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
-  local tableoffset=lookupoffset+offset
-  setposition(f,tableoffset)
-  local subtype=readushort(f)
-  if subtype==1 then
-    local coverage=readushort(f)
-    local subclasssets=readarray(f)
-    local rules={}
-    if subclasssets then
-      coverage=readcoverage(f,tableoffset+coverage,true)
-      for i=1,#subclasssets do
-        local offset=subclasssets[i]
-        if offset>0 then
-          local firstcoverage=coverage[i]
-          local rulesoffset=tableoffset+offset
-          local subclassrules=readarray(f,rulesoffset)
-          for rule=1,#subclassrules do
-            setposition(f,rulesoffset+subclassrules[rule])
-            local nofbefore=readushort(f)
-            local before
-            if nofbefore>0 then
-              before={}
-              for i=1,nofbefore do
-                before[i]={ readushort(f) }
-              end
-            end
-            local nofcurrent=readushort(f)
-            local current={ { firstcoverage } }
-            for i=2,nofcurrent do
-              current[i]={ readushort(f) }
-            end
-            local nofafter=readushort(f)
-            local after
-            if nofafter>0 then
-              after={}
-              for i=1,nofafter do
-                after[i]={ readushort(f) }
-              end
-            end
-            local noflookups=readushort(f)
-            local lookups=readlookuparray(f,noflookups,nofcurrent)
-            rules[#rules+1]={
-              before=before,
-              current=current,
-              after=after,
-              lookups=lookups,
-            }
-          end
-        end
-      end
-    else
-      report("empty subclassset in %a subtype %i","chainedcontext",subtype)
-    end
-    return {
-      format="glyphs",
-      rules=rules,
-    }
-  elseif subtype==2 then
-    local coverage=readushort(f)
-    local beforeclassdef=readushort(f)
-    local currentclassdef=readushort(f)
-    local afterclassdef=readushort(f)
-    local subclasssets=readarray(f)
-    local rules={}
-    if subclasssets then
-      local coverage=readcoverage(f,tableoffset+coverage)
-      local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs)
-      local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage)
-      local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs)
-      local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs)
-      local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs)
-      local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs)
-      for class=1,#subclasssets do
-        local offset=subclasssets[class]
-        if offset>0 then
-          local firstcoverage=currentclasses[class]
-          if firstcoverage then
-            firstcoverage=covered(firstcoverage,coverage) 
-            if firstcoverage then
-              local rulesoffset=tableoffset+offset
-              local subclassrules=readarray(f,rulesoffset)
-              for rule=1,#subclassrules do
-                setposition(f,rulesoffset+subclassrules[rule])
-                local nofbefore=readushort(f)
-                local before
-                if nofbefore>0 then
-                  before={}
-                  for i=1,nofbefore do
-                    before[i]=beforeclasses[readushort(f)+1]
-                  end
-                end
-                local nofcurrent=readushort(f)
-                local current={ firstcoverage }
-                for i=2,nofcurrent do
-                  current[i]=currentclasses[readushort(f)+1]
-                end
-                local nofafter=readushort(f)
-                local after
-                if nofafter>0 then
-                  after={}
-                  for i=1,nofafter do
-                    after[i]=afterclasses[readushort(f)+1]
-                  end
-                end
-                local noflookups=readushort(f)
-                local lookups=readlookuparray(f,noflookups,nofcurrent)
-                rules[#rules+1]={
-                  before=before,
-                  current=current,
-                  after=after,
-                  lookups=lookups,
-                }
-              end
-            else
-              report("no coverage")
-            end
-          else
-            report("class is not covered")
-          end
-        end
-      end
-    else
-      report("empty subclassset in %a subtype %i","chainedcontext",subtype)
-    end
-    return {
-      format="class",
-      rules=rules,
-    }
-  elseif subtype==3 then
-    local before=readarray(f)
-    local current=readarray(f)
-    local after=readarray(f)
-    local noflookups=readushort(f)
-    local lookups=readlookuparray(f,noflookups,#current)
-    before=readcoveragearray(f,tableoffset,before,true)
-    current=readcoveragearray(f,tableoffset,current,true)
-    after=readcoveragearray(f,tableoffset,after,true)
-    return {
-      format="coverage",
-      rules={
-        {
-          before=before,
-          current=current,
-          after=after,
-          lookups=lookups,
-        }
-      }
-    }
-  else
-    report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what)
-  end
-end
-local function extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,types,handlers,what)
-  local tableoffset=lookupoffset+offset
-  setposition(f,tableoffset)
-  local subtype=readushort(f)
-  if subtype==1 then
-    local lookuptype=types[readushort(f)]
-    local faroffset=readulong(f)
-    local handler=handlers[lookuptype]
-    if handler then
-      return handler(f,fontdata,lookupid,tableoffset+faroffset,0,glyphs,nofglyphs),lookuptype
-    else
-      report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension")
-    end
-  else
-    report("unsupported subtype %a in %s %s",subtype,what,"extension")
-  end
-end
-function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  local tableoffset=lookupoffset+offset
-  setposition(f,tableoffset)
-  local subtype=readushort(f)
-  if subtype==1 then
-    local coverage=readushort(f)
-    local delta=readshort(f) 
-    local coverage=readcoverage(f,tableoffset+coverage) 
-    for index in next,coverage do
-      local newindex=index+delta
-      if index>nofglyphs or newindex>nofglyphs then
-        report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
-        coverage[index]=nil
-      else
-        coverage[index]=newindex
-      end
-    end
-    return {
-      coverage=coverage
-    }
-  elseif subtype==2 then 
-    local coverage=readushort(f)
-    local nofreplacements=readushort(f)
-    local replacements={}
-    for i=1,nofreplacements do
-      replacements[i]=readushort(f)
-    end
-    local coverage=readcoverage(f,tableoffset+coverage) 
-    for index,newindex in next,coverage do
-      newindex=newindex+1
-      if index>nofglyphs or newindex>nofglyphs then
-        report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
-        coverage[index]=nil
-      else
-        coverage[index]=replacements[newindex]
-      end
-    end
-    return {
-      coverage=coverage
-    }
-  else
-    report("unsupported subtype %a in %a substitution",subtype,"single")
-  end
-end
-local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
-  local tableoffset=lookupoffset+offset
-  setposition(f,tableoffset)
-  local subtype=readushort(f)
-  if subtype==1 then
-    local coverage=readushort(f)
-    local nofsequence=readushort(f)
-    local sequences={}
-    for i=1,nofsequence do
-      sequences[i]=readushort(f)
-    end
-    for i=1,nofsequence do
-      setposition(f,tableoffset+sequences[i])
-      local n=readushort(f)
-      local s={}
-      for i=1,n do
-        s[i]=readushort(f)
-      end
-      sequences[i]=s
-    end
-    local coverage=readcoverage(f,tableoffset+coverage)
-    for index,newindex in next,coverage do
-      newindex=newindex+1
-      if index>nofglyphs or newindex>nofglyphs then
-        report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs)
-        coverage[index]=nil
-      else
-        coverage[index]=sequences[newindex]
-      end
-    end
-    return {
-      coverage=coverage
-    }
-  else
-    report("unsupported subtype %a in %a substitution",subtype,what)
-  end
-end
-function gsubhandlers.multiple(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple")
-end
-function gsubhandlers.alternate(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate")
-end
-function gsubhandlers.ligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  local tableoffset=lookupoffset+offset
-  setposition(f,tableoffset)
-  local subtype=readushort(f)
-  if subtype==1 then
-    local coverage=readushort(f)
-    local nofsets=readushort(f)
-    local ligatures={}
-    for i=1,nofsets do
-      ligatures[i]=readushort(f)
-    end
-    for i=1,nofsets do
-      local offset=lookupoffset+offset+ligatures[i]
-      setposition(f,offset)
-      local n=readushort(f)
-      local l={}
-      for i=1,n do
-        l[i]=offset+readushort(f)
-      end
-      ligatures[i]=l
-    end
-    local coverage=readcoverage(f,tableoffset+coverage)
-    for index,newindex in next,coverage do
-      local hash={}
-      local ligatures=ligatures[newindex+1]
-      for i=1,#ligatures do
-        local offset=ligatures[i]
-        setposition(f,offset)
-        local lig=readushort(f)
-        local cnt=readushort(f)
-        local hsh=hash
-        for i=2,cnt do
-          local c=readushort(f)
-          local h=hsh[c]
-          if not h then
-            h={}
-            hsh[c]=h
-          end
-          hsh=h
-        end
-        hsh.ligature=lig
-      end
-      coverage[index]=hash
-    end
-    return {
-      coverage=coverage
-    }
-  else
-    report("unsupported subtype %a in %a substitution",subtype,"ligature")
-  end
-end
-function gsubhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"context"
-end
-function gsubhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"chainedcontext"
-end
-function gsubhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution")
-end
-function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  local tableoffset=lookupoffset+offset
-  setposition(f,tableoffset)
-  local subtype=readushort(f)
-  if subtype==1 then 
-    local current=readfirst(f)
-    local before=readarray(f)
-    local after=readarray(f)
-    local replacements=readarray(f)
-    current=readcoveragearray(f,tableoffset,current,true)
-    before=readcoveragearray(f,tableoffset,before,true)
-    after=readcoveragearray(f,tableoffset,after,true)
-    return {
-      coverage={
-        format="reversecoverage",
-        before=before,
-        current=current,
-        after=after,
-        replacements=replacements,
-      }
-    },"reversechainedcontextsingle"
-  else
-    report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle")
-  end
-end
-local function readpairsets(f,tableoffset,sets,format1,format2)
-  local done={}
-  for i=1,#sets do
-    local offset=sets[i]
-    local reused=done[offset]
-    if not reused then
-      setposition(f,tableoffset+offset)
-      local n=readushort(f)
-      reused={}
-      for i=1,n do
-        reused[i]={
-          readushort(f),
-          readposition(f,format1),
-          readposition(f,format2)
-        }
-      end
-      done[offset]=reused
-    end
-    sets[i]=reused
-  end
-  return sets
-end
-local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2)
-  local classlist1={}
-  for i=1,nofclasses1 do
-    local classlist2={}
-    classlist1[i]=classlist2
-    for j=1,nofclasses2 do
-      local one=readposition(f,format1)
-      local two=readposition(f,format2)
-      if one or two then
-        classlist2[j]={ one,two }
-      else
-        classlist2[j]=false
-      end
-    end
-  end
-  return classlist1
-end
-function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  local tableoffset=lookupoffset+offset
-  setposition(f,tableoffset)
-  local subtype=readushort(f)
-  if subtype==1 then
-    local coverage=readushort(f)
-    local format=readushort(f)
-    local value=readposition(f,format)
-    local coverage=readcoverage(f,tableoffset+coverage)
-    for index,newindex in next,coverage do
-      coverage[index]=value
-    end
-    return {
-      format="pair",
-      coverage=coverage
-    }
-  elseif subtype==2 then
-    local coverage=readushort(f)
-    local format=readushort(f)
-    local values={}
-    local nofvalues=readushort(f)
-    for i=1,nofvalues do
-      values[i]=readposition(f,format)
-    end
-    local coverage=readcoverage(f,tableoffset+coverage)
-    for index,newindex in next,coverage do
-      coverage[index]=values[newindex+1]
-    end
-    return {
-      format="pair",
-      coverage=coverage
-    }
-  else
-    report("unsupported subtype %a in %a positioning",subtype,"single")
-  end
-end
-function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  local tableoffset=lookupoffset+offset
-  setposition(f,tableoffset)
-  local subtype=readushort(f)
-  if subtype==1 then
-    local coverage=readushort(f)
-    local format1=readushort(f)
-    local format2=readushort(f)
-    local sets=readarray(f)
-       sets=readpairsets(f,tableoffset,sets,format1,format2)
-       coverage=readcoverage(f,tableoffset+coverage)
-    for index,newindex in next,coverage do
-      local set=sets[newindex+1]
-      local hash={}
-      for i=1,#set do
-        local value=set[i]
-        if value then
-          local other=value[1]
-          local first=value[2]
-          local second=value[3]
-          if first or second then
-            hash[other]={ first,second } 
-          else
-            hash[other]=nil
-          end
-        end
-      end
-      coverage[index]=hash
-    end
-    return {
-      format="pair",
-      coverage=coverage
-    }
-  elseif subtype==2 then
-    local coverage=readushort(f)
-    local format1=readushort(f)
-    local format2=readushort(f)
-    local classdef1=readushort(f)
-    local classdef2=readushort(f)
-    local nofclasses1=readushort(f) 
-    local nofclasses2=readushort(f) 
-    local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2)
-       coverage=readcoverage(f,tableoffset+coverage)
-       classdef1=readclassdef(f,tableoffset+classdef1,coverage)
-       classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs)
-    local usedcoverage={}
-    for g1,c1 in next,classdef1 do
-      if coverage[g1] then
-        local l1=classlist[c1]
-        if l1 then
-          local hash={}
-          for paired,class in next,classdef2 do
-            local offsets=l1[class]
-            if offsets then
-              local first=offsets[1]
-              local second=offsets[2]
-              if first or second then
-                hash[paired]={ first,second }
-              else
-              end
-            end
-          end
-          usedcoverage[g1]=hash
-        end
-      end
-    end
-    return {
-      format="pair",
-      coverage=usedcoverage
-    }
-  elseif subtype==3 then
-    report("yet unsupported subtype %a in %a positioning",subtype,"pair")
-  else
-    report("unsupported subtype %a in %a positioning",subtype,"pair")
-  end
-end
-function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  local tableoffset=lookupoffset+offset
-  setposition(f,tableoffset)
-  local subtype=readushort(f)
-  if subtype==1 then
-    local coverage=tableoffset+readushort(f)
-    local nofrecords=readushort(f)
-    local records={}
-    for i=1,nofrecords do
-      local entry=readushort(f)
-      local exit=readushort(f)
-      records[i]={
-        entry=entry~=0 and (tableoffset+entry) or false,
-        exit=exit~=0 and (tableoffset+exit ) or false,
-      }
-    end
-    coverage=readcoverage(f,coverage)
-    for i=1,nofrecords do
-      local r=records[i]
-      records[i]={
-        1,
-        readanchor(f,r.entry) or nil,
-        readanchor(f,r.exit ) or nil,
-      }
-    end
-    for index,newindex in next,coverage do
-      coverage[index]=records[newindex+1]
-    end
-    return {
-      coverage=coverage
-    }
-  else
-    report("unsupported subtype %a in %a positioning",subtype,"cursive")
-  end
-end
-local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,ligature)
-  local tableoffset=lookupoffset+offset
-  setposition(f,tableoffset)
-  local subtype=readushort(f)
-  if subtype==1 then
-    local markcoverage=tableoffset+readushort(f)
-    local basecoverage=tableoffset+readushort(f)
-    local nofclasses=readushort(f)
-    local markoffset=tableoffset+readushort(f)
-    local baseoffset=tableoffset+readushort(f)
-    local markcoverage=readcoverage(f,markcoverage)
-    local basecoverage=readcoverage(f,basecoverage,true)
-    setposition(f,markoffset)
-    local markclasses={}
-    local nofmarkclasses=readushort(f)
-    local lastanchor=fontdata.lastanchor or 0
-    local usedanchors={}
-    for i=1,nofmarkclasses do
-      local class=readushort(f)+1
-      local offset=readushort(f)
-      if offset==0 then
-        markclasses[i]=false
-      else
-        markclasses[i]={ class,markoffset+offset }
-      end
-      usedanchors[class]=true
-    end
-    for i=1,nofmarkclasses do
-      local mc=markclasses[i]
-      if mc then
-        mc[2]=readanchor(f,mc[2])
-      end
-    end
-    setposition(f,baseoffset)
-    local nofbaserecords=readushort(f)
-    local baserecords={}
-    if ligature then
-      for i=1,nofbaserecords do 
-        local offset=readushort(f)
-        if offset==0 then
-          baserecords[i]=false
-        else
-          baserecords[i]=baseoffset+offset
-        end
-      end
-      for i=1,nofbaserecords do
-        local recordoffset=baserecords[i]
-        if recordoffset then
-          setposition(f,recordoffset)
-          local nofcomponents=readushort(f)
-          local components={}
-          for i=1,nofcomponents do
-            local classes={}
-            for i=1,nofclasses do
-              local offset=readushort(f)
-              if offset~=0 then
-                classes[i]=recordoffset+offset
-              else
-                classes[i]=false
-              end
-            end
-            components[i]=classes
-          end
-          baserecords[i]=components
-        end
-      end
-      local baseclasses={} 
-      for i=1,nofclasses do
-        baseclasses[i]={}
-      end
-      for i=1,nofbaserecords do
-        local components=baserecords[i]
-        if components then
-          local b=basecoverage[i]
-          for c=1,#components do
-            local classes=components[c]
-            if classes then
-              for i=1,nofclasses do
-                local anchor=readanchor(f,classes[i])
-                local bclass=baseclasses[i]
-                local bentry=bclass[b]
-                if bentry then
-                  bentry[c]=anchor
-                else
-                  bclass[b]={ [c]=anchor }
-                end
-              end
-            end
-          end
-        end
-      end
-      for index,newindex in next,markcoverage do
-        markcoverage[index]=markclasses[newindex+1] or nil
-      end
-      return {
-        format="ligature",
-        baseclasses=baseclasses,
-        coverage=markcoverage,
-      }
-    else
-      for i=1,nofbaserecords do
-        local r={}
-        for j=1,nofclasses do
-          local offset=readushort(f)
-          if offset==0 then
-            r[j]=false
-          else
-            r[j]=baseoffset+offset
-          end
-        end
-        baserecords[i]=r
-      end
-      local baseclasses={} 
-      for i=1,nofclasses do
-        baseclasses[i]={}
-      end
-      for i=1,nofbaserecords do
-        local r=baserecords[i]
-        local b=basecoverage[i]
-        for j=1,nofclasses do
-          baseclasses[j][b]=readanchor(f,r[j])
-        end
-      end
-      for index,newindex in next,markcoverage do
-        markcoverage[index]=markclasses[newindex+1] or nil
-      end
-      return {
-        format="base",
-        baseclasses=baseclasses,
-        coverage=markcoverage,
-      }
-    end
-  else
-    report("unsupported subtype %a in",subtype)
-  end
-end
-function gposhandlers.marktobase(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-end
-function gposhandlers.marktoligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true)
-end
-function gposhandlers.marktomark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-end
-function gposhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"context"
-end
-function gposhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"chainedcontext"
-end
-function gposhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
-  return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning")
-end
-do
-  local plugins={}
-  function plugins.size(f,fontdata,tableoffset,feature)
-    if fontdata.designsize then
-    else
-      local function check(offset)
-        setposition(f,offset)
-        local designsize=readushort(f)
-        if designsize>0 then 
-          local fontstyle=readushort(f)
-          local guimenuid=readushort(f)
-          local minsize=readushort(f)
-          local maxsize=readushort(f)
-          if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then
-            minsize=designsize
-            maxsize=designsize
-          end
-          if designsize>=minsize and designsize<=maxsize then
-            return minsize,maxsize,designsize
-          end
-        end
-      end
-      local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters)
-      if not designsize then
-        minsize,maxsize,designsize=check(tableoffset+feature.parameters)
-        if designsize then
-          report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?")
-        else
-          report("bad size feature in %a,",fontdata.filename or "?")
-        end
-      end
-      if designsize then
-        fontdata.minsize=minsize
-        fontdata.maxsize=maxsize
-        fontdata.designsize=designsize
-      end
-    end
-  end
-  local function reorderfeatures(fontdata,scripts,features)
-    local scriptlangs={}
-    local featurehash={}
-    local featureorder={}
-    for script,languages in next,scripts do
-      for language,record in next,languages do
-        local hash={}
-        local list=record.featureindices
-        for k=1,#list do
-          local index=list[k]
-          local feature=features[index]
-          local lookups=feature.lookups
-          local tag=feature.tag
-          if tag then
-            hash[tag]=true
-          end
-          if lookups then
-            for i=1,#lookups do
-              local lookup=lookups[i]
-              local o=featureorder[lookup]
-              if o then
-                local okay=true
-                for i=1,#o do
-                  if o[i]==tag then
-                    okay=false
-                    break
-                  end
-                end
-                if okay then
-                  o[#o+1]=tag
-                end
-              else
-                featureorder[lookup]={ tag }
-              end
-              local f=featurehash[lookup]
-              if f then
-                local h=f[tag]
-                if h then
-                  local s=h[script]
-                  if s then
-                    s[language]=true
-                  else
-                    h[script]={ [language]=true }
-                  end
-                else
-                  f[tag]={ [script]={ [language]=true } }
-                end
-              else
-                featurehash[lookup]={ [tag]={ [script]={ [language]=true } } }
-              end
-              local h=scriptlangs[tag]
-              if h then
-                local s=h[script]
-                if s then
-                  s[language]=true
-                else
-                  h[script]={ [language]=true }
-                end
-              else
-                scriptlangs[tag]={ [script]={ [language]=true } }
-              end
-            end
-          end
-        end
-      end
-    end
-    return scriptlangs,featurehash,featureorder
-  end
-  local function readscriplan(f,fontdata,scriptoffset)
-    setposition(f,scriptoffset)
-    local nofscripts=readushort(f)
-    local scripts={}
-    for i=1,nofscripts do
-      scripts[readtag(f)]=scriptoffset+readushort(f)
-    end
-    local languagesystems=setmetatableindex("table")
-    for script,offset in next,scripts do
-      setposition(f,offset)
-      local defaultoffset=readushort(f)
-      local noflanguages=readushort(f)
-      local languages={}
-      if defaultoffset>0 then
-        languages.dflt=languagesystems[offset+defaultoffset]
-      end
-      for i=1,noflanguages do
-        local language=readtag(f)
-        local offset=offset+readushort(f)
-        languages[language]=languagesystems[offset]
-      end
-      scripts[script]=languages
-    end
-    for offset,usedfeatures in next,languagesystems do
-      if offset>0 then
-        setposition(f,offset)
-        local featureindices={}
-        usedfeatures.featureindices=featureindices
-        usedfeatures.lookuporder=readushort(f) 
-        usedfeatures.requiredindex=readushort(f) 
-        local noffeatures=readushort(f)
-        for i=1,noffeatures do
-          featureindices[i]=readushort(f)+1
-        end
-      end
-    end
-    return scripts
-  end
-  local function readfeatures(f,fontdata,featureoffset)
-    setposition(f,featureoffset)
-    local features={}
-    local noffeatures=readushort(f)
-    for i=1,noffeatures do
-      features[i]={
-        tag=readtag(f),
-        offset=readushort(f)
-      }
-    end
-    for i=1,noffeatures do
-      local feature=features[i]
-      local offset=featureoffset+feature.offset
-      setposition(f,offset)
-      local parameters=readushort(f) 
-      local noflookups=readushort(f)
-      if noflookups>0 then
-        local lookups={}
-        feature.lookups=lookups
-        for j=1,noflookups do
-          lookups[j]=readushort(f)+1
-        end
-      end
-      if parameters>0 then
-        feature.parameters=parameters
-        local plugin=plugins[feature.tag]
-        if plugin then
-          plugin(f,fontdata,featureoffset,feature)
-        end
-      end
-    end
-    return features
-  end
-  local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
-    setposition(f,lookupoffset)
-    local lookups={}
-    local noflookups=readushort(f)
-    for i=1,noflookups do
-      lookups[i]=readushort(f)
-    end
-    for lookupid=1,noflookups do
-      local index=lookups[lookupid]
-      setposition(f,lookupoffset+index)
-      local subtables={}
-      local typebits=readushort(f)
-      local flagbits=readushort(f)
-      local lookuptype=lookuptypes[typebits]
-      local lookupflags=lookupflags[flagbits]
-      local nofsubtables=readushort(f)
-      for j=1,nofsubtables do
-        local offset=readushort(f)
-        subtables[j]=offset+index 
-      end
-      local markclass=bittest(flagbits,0x0010) 
-      if markclass then
-        markclass=readushort(f) 
-      end
-      local markset=rshift(flagbits,8)
-      if markset>0 then
-        markclass=markset 
-      end
-      lookups[lookupid]={
-        type=lookuptype,
-        flags=lookupflags,
-        name=lookupid,
-        subtables=subtables,
-        markclass=markclass,
-        features=featurehash[lookupid],
-        order=featureorder[lookupid],
-      }
-    end
-    return lookups
-  end
-  local function readscriptoffsets(f,fontdata,tableoffset)
-    if not tableoffset then
-      return
-    end
-    setposition(f,tableoffset)
-    local version=readulong(f)
-    if version~=0x00010000 then
-      report("table version %a of %a is not supported (yet), maybe font %s is bad",version,what,fontdata.filename)
-      return
-    end
-    return tableoffset+readushort(f),tableoffset+readushort(f),tableoffset+readushort(f)
-  end
-  local f_lookupname=formatters["%s_%s_%s"]
-  local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what)
-    local sequences=fontdata.sequences  or {}
-    local sublookuplist=fontdata.sublookups or {}
-    fontdata.sequences=sequences
-    fontdata.sublookups=sublookuplist
-    local nofsublookups=#sublookuplist
-    local nofsequences=#sequences 
-    local lastsublookup=nofsublookups
-    local lastsequence=nofsequences
-    local lookupnames=lookupnames[what]
-    local sublookuphash={}
-    local sublookupcheck={}
-    local glyphs=fontdata.glyphs
-    local nofglyphs=fontdata.nofglyphs or #glyphs
-    local noflookups=#lookups
-    local lookupprefix=sub(what,2,2)
-    for lookupid=1,noflookups do
-      local lookup=lookups[lookupid]
-      local lookuptype=lookup.type
-      local subtables=lookup.subtables
-      local features=lookup.features
-      local handler=lookuphandlers[lookuptype]
-      if handler then
-        local nofsubtables=#subtables
-        local order=lookup.order
-        local flags=lookup.flags
-        if flags[1] then flags[1]="mark" end
-        if flags[2] then flags[2]="ligature" end
-        if flags[3] then flags[3]="base" end
-        local markclass=lookup.markclass
-        if nofsubtables>0 then
-          local steps={}
-          local nofsteps=0
-          local oldtype=nil
-          for s=1,nofsubtables do
-            local step,lt=handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs)
-            if lt then
-              lookuptype=lt
-              if oldtype and lt~=oldtype then
-                report("messy %s lookup type %a and %a",what,lookuptype,oldtype)
-              end
-              oldtype=lookuptype
-            end
-            if not step then
-              report("unsupported %s lookup type %a",what,lookuptype)
-            else
-              nofsteps=nofsteps+1
-              steps[nofsteps]=step
-              local rules=step.rules
-              if rules then
-                for i=1,#rules do
-                  local rule=rules[i]
-                  local before=rule.before
-                  local current=rule.current
-                  local after=rule.after
-                  if before then
-                    for i=1,#before do
-                      before[i]=tohash(before[i])
-                    end
-                    rule.before=reversed(before)
-                  end
-                  if current then
-                    for i=1,#current do
-                      current[i]=tohash(current[i])
-                    end
-                  end
-                  if after then
-                    for i=1,#after do
-                      after[i]=tohash(after[i])
-                    end
-                  end
-                end
-              end
-            end
-          end
-          if nofsteps~=nofsubtables then
-            report("bogus subtables removed in %s lookup type %a",what,lookuptype)
-          end
-          lookuptype=lookupnames[lookuptype] or lookuptype
-          if features then
-            nofsequences=nofsequences+1
-            local l={
-              index=nofsequences,
-              name=f_lookupname(lookupprefix,"s",lookupid+lookupidoffset),
-              steps=steps,
-              nofsteps=nofsteps,
-              type=lookuptype,
-              markclass=markclass or nil,
-              flags=flags,
-              order=order,
-              features=features,
-            }
-            sequences[nofsequences]=l
-            lookup.done=l
-          else
-            nofsublookups=nofsublookups+1
-            local l={
-              index=nofsublookups,
-              name=f_lookupname(lookupprefix,"l",lookupid+lookupidoffset),
-              steps=steps,
-              nofsteps=nofsteps,
-              type=lookuptype,
-              markclass=markclass or nil,
-              flags=flags,
-            }
-            sublookuplist[nofsublookups]=l
-            sublookuphash[lookupid]=nofsublookups
-            sublookupcheck[lookupid]=0
-            lookup.done=l
-          end
-        else
-          report("no subtables for lookup %a",lookupid)
-        end
-      else
-        report("no handler for lookup %a with type %a",lookupid,lookuptype)
-      end
-    end
-    local reported={}
-    local function report_issue(i,what,sequence,kind)
-      local name=sequence.name
-      if not reported[name] then
-        report("rule %i in %s lookup %a has %s lookups",i,what,name,kind)
-        reported[name]=true
-      end
-    end
-    for i=lastsequence+1,nofsequences do
-      local sequence=sequences[i]
-      local steps=sequence.steps
-      for i=1,#steps do
-        local step=steps[i]
-        local rules=step.rules
-        if rules then
-          for i=1,#rules do
-            local rule=rules[i]
-            local rlookups=rule.lookups
-            if not rlookups then
-              report_issue(i,what,sequence,"no")
-            elseif not next(rlookups) then
-              report_issue(i,what,sequence,"empty")
-              rule.lookups=nil
-            else
-              local length=#rlookups
-              for index=1,length do
-                local lookupid=rlookups[index]
-                if lookupid then
-                  local h=sublookuphash[lookupid]
-                  if not h then
-                    local lookup=lookups[lookupid]
-                    if lookup then
-                      local d=lookup.done
-                      if d then
-                        nofsublookups=nofsublookups+1
-                        h={
-                          index=nofsublookups,
-                          name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset),
-                          derived=true,
-                          steps=d.steps,
-                          nofsteps=d.nofsteps,
-                          type=d.lookuptype,
-                          markclass=d.markclass or nil,
-                          flags=d.flags,
-                        }
-                        sublookuplist[nofsublookups]=copy(h) 
-                        sublookuphash[lookupid]=nofsublookups
-                        sublookupcheck[lookupid]=1
-                        h=nofsublookups 
-                      else
-                        report_issue(i,what,sequence,"missing")
-                        rule.lookups=nil
-                        break
-                      end
-                    else
-                      report_issue(i,what,sequence,"bad")
-                      rule.lookups=nil
-                      break
-                    end
-                  else
-                    sublookupcheck[lookupid]=sublookupcheck[lookupid]+1
-                  end
-                  rlookups[index]=h or false
-                else
-                  rlookups[index]=false
-                end
-              end
-            end
-          end
-        end
-      end
-    end
-    for i,n in sortedhash(sublookupcheck) do
-      local l=lookups[i]
-      local t=l.type
-      if n==0 and t~="extension" then
-        local d=l.done
-        report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t)
-      end
-    end
-  end
-  local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo)
-    local datatable=fontdata.tables[what]
-    if not datatable then
-      return
-    end
-    local tableoffset=datatable.offset
-    if not tableoffset then
-      return
-    end
-    local scriptoffset,featureoffset,lookupoffset=readscriptoffsets(f,fontdata,tableoffset)
-    if not scriptoffset then
-      return
-    end
-    local scripts=readscriplan(f,fontdata,scriptoffset)
-    local features=readfeatures(f,fontdata,featureoffset)
-    local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features)
-    if fontdata.features then
-      fontdata.features[what]=scriptlangs
-    else
-      fontdata.features={ [what]=scriptlangs }
-    end
-    if not lookupstoo then
-      return
-    end
-    local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
-    if lookups then
-      resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what)
-    end
-  end
-  local function checkkerns(f,fontdata,specification)
-    local datatable=fontdata.tables.kern
-    if not datatable then
-      return 
-    end
-    local features=fontdata.features
-    local gposfeatures=features and features.gpos
-    local name
-    if not gposfeatures or not gposfeatures.kern then
-      name="kern"
-    elseif specification.globalkerns then
-      name="globalkern"
-    else
-      report("ignoring global kern table using gpos kern feature")
-      return
-    end
-    report("adding global kern table as gpos feature %a",name)
-    setposition(f,datatable.offset)
-    local version=readushort(f)
-    local noftables=readushort(f)
-    local kerns=setmetatableindex("table")
-    for i=1,noftables do
-      local version=readushort(f)
-      local length=readushort(f)
-      local coverage=readushort(f)
-      local format=bit32.rshift(coverage,8) 
-      if format==0 then
-        local nofpairs=readushort(f)
-        local searchrange=readushort(f)
-        local entryselector=readushort(f)
-        local rangeshift=readushort(f)
-        for i=1,nofpairs do
-          kerns[readushort(f)][readushort(f)]=readfword(f)
-        end
-      elseif format==2 then
-      else
-      end
-    end
-    local feature={ dflt={ dflt=true } }
-    if not features then
-      fontdata.features={ gpos={ [name]=feature } }
-    elseif not gposfeatures then
-      fontdata.features.gpos={ [name]=feature }
-    else
-      gposfeatures[name]=feature
-    end
-    local sequences=fontdata.sequences
-    if not sequences then
-      sequences={}
-      fontdata.sequences=sequences
-    end
-    local nofsequences=#sequences+1
-    sequences[nofsequences]={
-      index=nofsequences,
-      name=name,
-      steps={
-        {
-          coverage=kerns,
-          format="kern",
-        },
-      },
-      nofsteps=1,
-      type="gpos_pair",
-      flags={ false,false,false,false },
-      order={ name },
-      features={ [name]=feature },
-    }
-  end
-  function readers.gsub(f,fontdata,specification)
-    if specification.details then
-      readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups)
-    end
-  end
-  function readers.gpos(f,fontdata,specification)
-    if specification.details then
-      readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups)
-      if specification.lookups then
-        checkkerns(f,fontdata,specification)
-      end
-    end
-  end
-end
-function readers.gdef(f,fontdata,specification)
-  if specification.glyphs then
-    local datatable=fontdata.tables.gdef
-    if datatable then
-      local tableoffset=datatable.offset
-      setposition(f,tableoffset)
-      local version=readulong(f)
-      local classoffset=tableoffset+readushort(f)
-      local attachmentoffset=tableoffset+readushort(f) 
-      local ligaturecarets=tableoffset+readushort(f) 
-      local markclassoffset=tableoffset+readushort(f)
-      local marksetsoffset=version==0x00010002 and (tableoffset+readushort(f))
-      local glyphs=fontdata.glyphs
-      local marks={}
-      local markclasses=setmetatableindex("table")
-      local marksets=setmetatableindex("table")
-      fontdata.marks=marks
-      fontdata.markclasses=markclasses
-      fontdata.marksets=marksets
-      setposition(f,classoffset)
-      local classformat=readushort(f)
-      if classformat==1 then
-        local firstindex=readushort(f)
-        local lastindex=firstindex+readushort(f)-1
-        for index=firstindex,lastindex do
-          local class=classes[readushort(f)]
-          if class=="mark" then
-            marks[index]=true
-          end
-          glyphs[index].class=class
-        end
-      elseif classformat==2 then
-        local nofranges=readushort(f)
-        for i=1,nofranges do
-          local firstindex=readushort(f)
-          local lastindex=readushort(f)
-          local class=classes[readushort(f)]
-          if class then
-            for index=firstindex,lastindex do
-              glyphs[index].class=class
-              if class=="mark" then
-                marks[index]=true
-              end
-            end
-          end
-        end
-      end
-      setposition(f,markclassoffset)
-      local classformat=readushort(f)
-      if classformat==1 then
-        local firstindex=readushort(f)
-        local lastindex=firstindex+readushort(f)-1
-        for index=firstindex,lastindex do
-          markclasses[readushort(f)][index]=true
-        end
-      elseif classformat==2 then
-        local nofranges=readushort(f)
-        for i=1,nofranges do
-          local firstindex=readushort(f)
-          local lastindex=readushort(f)
-          local class=markclasses[readushort(f)]
-          for index=firstindex,lastindex do
-            class[index]=true
-          end
-        end
-      end
-      if marksetsoffset and marksetsoffset>tableoffset then 
-        setposition(f,marksetsoffset)
-        local format=readushort(f)
-        if format==1 then
-          local nofsets=readushort(f)
-          local sets={}
-          for i=1,nofsets do
-            sets[i]=readulong(f)
-          end
-          for i=1,nofsets do
-            local offset=sets[i]
-            if offset~=0 then
-              marksets[i]=readcoverage(f,marksetsoffset+offset)
-            end
-          end
-        end
-      end
-    end
-  end
-end
-local function readmathvalue(f)
-  local v=readshort(f)
-  skipshort(f,1) 
-  return v
-end
-local function readmathconstants(f,fontdata,offset)
-  setposition(f,offset)
-  fontdata.mathconstants={
-    ScriptPercentScaleDown=readshort(f),
-    ScriptScriptPercentScaleDown=readshort(f),
-    DelimitedSubFormulaMinHeight=readushort(f),
-    DisplayOperatorMinHeight=readushort(f),
-    MathLeading=readmathvalue(f),
-    AxisHeight=readmathvalue(f),
-    AccentBaseHeight=readmathvalue(f),
-    FlattenedAccentBaseHeight=readmathvalue(f),
-    SubscriptShiftDown=readmathvalue(f),
-    SubscriptTopMax=readmathvalue(f),
-    SubscriptBaselineDropMin=readmathvalue(f),
-    SuperscriptShiftUp=readmathvalue(f),
-    SuperscriptShiftUpCramped=readmathvalue(f),
-    SuperscriptBottomMin=readmathvalue(f),
-    SuperscriptBaselineDropMax=readmathvalue(f),
-    SubSuperscriptGapMin=readmathvalue(f),
-    SuperscriptBottomMaxWithSubscript=readmathvalue(f),
-    SpaceAfterScript=readmathvalue(f),
-    UpperLimitGapMin=readmathvalue(f),
-    UpperLimitBaselineRiseMin=readmathvalue(f),
-    LowerLimitGapMin=readmathvalue(f),
-    LowerLimitBaselineDropMin=readmathvalue(f),
-    StackTopShiftUp=readmathvalue(f),
-    StackTopDisplayStyleShiftUp=readmathvalue(f),
-    StackBottomShiftDown=readmathvalue(f),
-    StackBottomDisplayStyleShiftDown=readmathvalue(f),
-    StackGapMin=readmathvalue(f),
-    StackDisplayStyleGapMin=readmathvalue(f),
-    StretchStackTopShiftUp=readmathvalue(f),
-    StretchStackBottomShiftDown=readmathvalue(f),
-    StretchStackGapAboveMin=readmathvalue(f),
-    StretchStackGapBelowMin=readmathvalue(f),
-    FractionNumeratorShiftUp=readmathvalue(f),
-    FractionNumeratorDisplayStyleShiftUp=readmathvalue(f),
-    FractionDenominatorShiftDown=readmathvalue(f),
-    FractionDenominatorDisplayStyleShiftDown=readmathvalue(f),
-    FractionNumeratorGapMin=readmathvalue(f),
-    FractionNumeratorDisplayStyleGapMin=readmathvalue(f),
-    FractionRuleThickness=readmathvalue(f),
-    FractionDenominatorGapMin=readmathvalue(f),
-    FractionDenominatorDisplayStyleGapMin=readmathvalue(f),
-    SkewedFractionHorizontalGap=readmathvalue(f),
-    SkewedFractionVerticalGap=readmathvalue(f),
-    OverbarVerticalGap=readmathvalue(f),
-    OverbarRuleThickness=readmathvalue(f),
-    OverbarExtraAscender=readmathvalue(f),
-    UnderbarVerticalGap=readmathvalue(f),
-    UnderbarRuleThickness=readmathvalue(f),
-    UnderbarExtraDescender=readmathvalue(f),
-    RadicalVerticalGap=readmathvalue(f),
-    RadicalDisplayStyleVerticalGap=readmathvalue(f),
-    RadicalRuleThickness=readmathvalue(f),
-    RadicalExtraAscender=readmathvalue(f),
-    RadicalKernBeforeDegree=readmathvalue(f),
-    RadicalKernAfterDegree=readmathvalue(f),
-    RadicalDegreeBottomRaisePercent=readshort(f),
-  }
-end
-local function readmathglyphinfo(f,fontdata,offset)
-  setposition(f,offset)
-  local italics=readushort(f)
-  local accents=readushort(f)
-  local extensions=readushort(f)
-  local kerns=readushort(f)
-  local glyphs=fontdata.glyphs
-  if italics~=0 then
-    setposition(f,offset+italics)
-    local coverage=readushort(f)
-    local nofglyphs=readushort(f)
-    coverage=readcoverage(f,offset+italics+coverage,true)
-    setposition(f,offset+italics+4)
-    for i=1,nofglyphs do
-      local italic=readmathvalue(f)
-      if italic~=0 then
-        local glyph=glyphs[coverage[i]]
-        local math=glyph.math
-        if not math then
-          glyph.math={ italic=italic }
-        else
-          math.italic=italic
-        end
-      end
-    end
-    fontdata.hasitalics=true
-  end
-  if accents~=0 then
-    setposition(f,offset+accents)
-    local coverage=readushort(f)
-    local nofglyphs=readushort(f)
-    coverage=readcoverage(f,offset+accents+coverage,true)
-    setposition(f,offset+accents+4)
-    for i=1,nofglyphs do
-      local accent=readmathvalue(f)
-      if accent~=0 then
-        local glyph=glyphs[coverage[i]]
-        local math=glyph.math
-        if not math then
-          glyph.math={ accent=accent }
-        else
-          math.accent=accent
-        end
-      end
-    end
-  end
-  if extensions~=0 then
-    setposition(f,offset+extensions)
-  end
-  if kerns~=0 then
-    local kernoffset=offset+kerns
-    setposition(f,kernoffset)
-    local coverage=readushort(f)
-    local nofglyphs=readushort(f)
-    if nofglyphs>0 then
-      local function get(offset)
-        setposition(f,kernoffset+offset)
-        local n=readushort(f)
-        if n==0 then
-          local k=readmathvalue(f)
-          if k==0 then
-          else
-            return { { kern=k } }
-          end
-        else
-          local l={}
-          for i=1,n do
-            l[i]={ height=readmathvalue(f) }
-          end
-          for i=1,n do
-            l[i].kern=readmathvalue(f)
-          end
-          l[n+1]={ kern=readmathvalue(f) }
-          return l
-        end
-      end
-      local kernsets={}
-      for i=1,nofglyphs do
-        local topright=readushort(f)
-        local topleft=readushort(f)
-        local bottomright=readushort(f)
-        local bottomleft=readushort(f)
-        kernsets[i]={
-          topright=topright~=0 and topright  or nil,
-          topleft=topleft~=0 and topleft   or nil,
-          bottomright=bottomright~=0 and bottomright or nil,
-          bottomleft=bottomleft~=0 and bottomleft or nil,
-        }
-      end
-      coverage=readcoverage(f,kernoffset+coverage,true)
-      for i=1,nofglyphs do
-        local kernset=kernsets[i]
-        if next(kernset) then
-          local k=kernset.topright  if k then kernset.topright=get(k) end
-          local k=kernset.topleft   if k then kernset.topleft=get(k) end
-          local k=kernset.bottomright if k then kernset.bottomright=get(k) end
-          local k=kernset.bottomleft if k then kernset.bottomleft=get(k) end
-          if next(kernset) then
-            local glyph=glyphs[coverage[i]]
-            local math=glyph.math
-            if math then
-              math.kerns=kernset
-            else
-              glyph.math={ kerns=kernset }
-            end
-          end
-        end
-      end
-    end
-  end
-end
-local function readmathvariants(f,fontdata,offset)
-  setposition(f,offset)
-  local glyphs=fontdata.glyphs
-  local minoverlap=readushort(f)
-  local vcoverage=readushort(f)
-  local hcoverage=readushort(f)
-  local vnofglyphs=readushort(f)
-  local hnofglyphs=readushort(f)
-  local vconstruction={}
-  local hconstruction={}
-  for i=1,vnofglyphs do
-    vconstruction[i]=readushort(f)
-  end
-  for i=1,hnofglyphs do
-    hconstruction[i]=readushort(f)
-  end
-  fontdata.mathconstants.MinConnectorOverlap=minoverlap
-  local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic)
-    if coverage~=0 and nofglyphs>0 then
-      local coverage=readcoverage(f,offset+coverage,true)
-      for i=1,nofglyphs do
-        local c=construction[i]
-        if c~=0 then
-          local index=coverage[i]
-          local glyph=glyphs[index]
-          local math=glyph.math
-          setposition(f,offset+c)
-          local assembly=readushort(f)
-          local nofvariants=readushort(f)
-          if nofvariants>0 then
-            local variants,v=nil,0
-            for i=1,nofvariants do
-              local variant=readushort(f)
-              if variant==index then
-              elseif variants then
-                v=v+1
-                variants[v]=variant
-              else
-                v=1
-                variants={ variant }
-              end
-              skipshort(f)
-            end
-            if not variants then
-            elseif not math then
-              math={ [kvariants]=variants }
-              glyph.math=math
-            else
-              math[kvariants]=variants
-            end
-          end
-          if assembly~=0 then
-            setposition(f,offset+c+assembly)
-            local italic=readmathvalue(f)
-            local nofparts=readushort(f)
-            local parts={}
-            for i=1,nofparts do
-              local p={
-                glyph=readushort(f),
-                start=readushort(f),
-                ["end"]=readushort(f),
-                advance=readushort(f),
-              }
-              local flags=readushort(f)
-              if bittest(flags,0x0001) then
-                p.extender=1 
-              end
-              parts[i]=p
-            end
-            if not math then
-              math={
-                [kparts]=parts
-              }
-              glyph.math=math
-            else
-              math[kparts]=parts
-            end
-            if italic and italic~=0 then
-              math[kitalic]=italic
-            end
-          end
-        end
-      end
-    end
-  end
-  get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic")
-  get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic")
-end
-function readers.math(f,fontdata,specification)
-  if specification.glyphs then
-    local datatable=fontdata.tables.math
-    if datatable then
-      local tableoffset=datatable.offset
-      setposition(f,tableoffset)
-      local version=readulong(f)
-      if version~=0x00010000 then
-        report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"math",fontdata.filename)
-        return
-      end
-      local constants=readushort(f)
-      local glyphinfo=readushort(f)
-      local variants=readushort(f)
-      if constants==0 then
-        report("the math table of %a has no constants",fontdata.filename)
-      else
-        readmathconstants(f,fontdata,tableoffset+constants)
-      end
-      if glyphinfo~=0 then
-        readmathglyphinfo(f,fontdata,tableoffset+glyphinfo)
-      end
-      if variants~=0 then
-        readmathvariants(f,fontdata,tableoffset+variants)
-      end
-    end
-  end
-end
-function readers.colr(f,fontdata,specification)
-  local datatable=fontdata.tables.colr
-  if datatable then
-    if specification.glyphs then
-      local tableoffset=datatable.offset
-      setposition(f,tableoffset)
-      local version=readushort(f)
-      if version~=0 then
-        report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename)
-        return
-      end
-      if not fontdata.tables.cpal then
-        report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal")
-        fontdata.colorpalettes={}
-      end
-      local glyphs=fontdata.glyphs
-      local nofglyphs=readushort(f)
-      local baseoffset=readulong(f)
-      local layeroffset=readulong(f)
-      local noflayers=readushort(f)
-      local layerrecords={}
-      local maxclass=0
-      setposition(f,tableoffset+layeroffset)
-      for i=1,noflayers do
-        local slot=readushort(f)
-        local class=readushort(f)
-        if class<0xFFFF then
-          class=class+1
-          if class>maxclass then
-            maxclass=class
-          end
-        end
-        layerrecords[i]={
-          slot=slot,
-          class=class,
-        }
-      end
-      fontdata.maxcolorclass=maxclass
-      setposition(f,tableoffset+baseoffset)
-      for i=0,nofglyphs-1 do
-        local glyphindex=readushort(f)
-        local firstlayer=readushort(f)
-        local noflayers=readushort(f)
-        local t={}
-        for i=1,noflayers do
-          t[i]=layerrecords[firstlayer+i]
-        end
-        glyphs[glyphindex].colors=t
-      end
-    end
-    fontdata.hascolor=true
-  end
-end
-function readers.cpal(f,fontdata,specification)
-  if specification.glyphs then
-    local datatable=fontdata.tables.cpal
-    if datatable then
-      local tableoffset=datatable.offset
-      setposition(f,tableoffset)
-      local version=readushort(f)
-      if version>1 then
-        report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"cpal",fontdata.filename)
-        return
-      end
-      local nofpaletteentries=readushort(f)
-      local nofpalettes=readushort(f)
-      local nofcolorrecords=readushort(f)
-      local firstcoloroffset=readulong(f)
-      local colorrecords={}
-      local palettes={}
-      for i=1,nofpalettes do
-        palettes[i]=readushort(f)
-      end
-      if version==1 then
-        local palettettypesoffset=readulong(f)
-        local palettelabelsoffset=readulong(f)
-        local paletteentryoffset=readulong(f)
-      end
-      setposition(f,tableoffset+firstcoloroffset)
-      for i=1,nofcolorrecords do
-        local b,g,r,a=readbytes(f,4)
-        colorrecords[i]={
-          r,g,b,a~=255 and a or nil,
-        }
-      end
-      for i=1,nofpalettes do
-        local p={}
-        local o=palettes[i]
-        for j=1,nofpaletteentries do
-          p[j]=colorrecords[o+j]
-        end
-        palettes[i]=p
-      end
-      fontdata.colorpalettes=palettes
-    end
-  end
-end
-function readers.svg(f,fontdata,specification)
-  local datatable=fontdata.tables.svg
-  if datatable then
-    if specification.glyphs then
-      local tableoffset=datatable.offset
-      setposition(f,tableoffset)
-      local version=readushort(f)
-      if version~=0 then
-        report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"svg",fontdata.filename)
-        return
-      end
-      local glyphs=fontdata.glyphs
-      local indexoffset=tableoffset+readulong(f)
-      local reserved=readulong(f)
-      setposition(f,indexoffset)
-      local nofentries=readushort(f)
-      local entries={}
-      for i=1,nofentries do
-        entries[i]={
-          first=readushort(f),
-          last=readushort(f),
-          offset=indexoffset+readulong(f),
-          length=readulong(f),
-        }
-      end
-      for i=1,nofentries do
-        local entry=entries[i]
-        setposition(f,entry.offset)
-        entries[i]={
-          first=entry.first,
-          last=entry.last,
-          data=readstring(f,entry.length)
-        }
-      end
-      fontdata.svgshapes=entries
-    end
-    fontdata.hascolor=true
-  end
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-dsp”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-oup” f7237130b648a4c2b477dabedc7f90e8] ---
-
-if not modules then modules={} end modules ['font-oup']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local next,type=next,type
-local P,R,S=lpeg.P,lpeg.R,lpeg.S
-local lpegmatch=lpeg.match
-local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack
-local formatters=string.formatters
-local sortedkeys=table.sortedkeys
-local sortedhash=table.sortedhash
-local tohash=table.tohash
-local report=logs.reporter("otf reader")
-local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end)
-local readers=fonts.handlers.otf.readers
-local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 
-local f_private=formatters["P%05X"]
-local f_unicode=formatters["U%05X"]
-local f_index=formatters["I%05X"]
-local f_character_y=formatters["%C"]
-local f_character_n=formatters["[ %C ]"]
-local check_duplicates=true 
-local check_soft_hyphen=false 
-directives.register("otf.checksofthyphen",function(v)
-  check_soft_hyphen=v
-end)
-local function replaced(list,index,replacement)
-  if type(list)=="number" then
-    return replacement
-  elseif type(replacement)=="table" then
-    local t={}
-    local n=index-1
-    for i=1,n do
-      t[i]=list[i]
-    end
-    for i=1,#replacement do
-      n=n+1
-      t[n]=replacement[i]
-    end
-    for i=index+1,#list do
-      n=n+1
-      t[n]=list[i]
-    end
-  else
-    list[index]=replacement
-    return list
-  end
-end
-local function unifyresources(fontdata,indices)
-  local descriptions=fontdata.descriptions
-  local resources=fontdata.resources
-  if not descriptions or not resources then
-    return
-  end
-  local variants=fontdata.resources.variants
-  if variants then
-    for selector,unicodes in next,variants do
-      for unicode,index in next,unicodes do
-        unicodes[unicode]=indices[index]
-      end
-    end
-  end
-  local function remark(marks)
-    if marks then
-      local newmarks={}
-      for k,v in next,marks do
-        local u=indices[k]
-        if u then
-          newmarks[u]=v
-        else
-          report("discarding mark %i",k)
-        end
-      end
-      return newmarks
-    end
-  end
-  local marks=resources.marks
-  if marks then
-    resources.marks=remark(marks)
-  end
-  local markclasses=resources.markclasses
-  if markclasses then
-    for class,marks in next,markclasses do
-      markclasses[class]=remark(marks)
-    end
-  end
-  local marksets=resources.marksets
-  if marksets then
-    for class,marks in next,marksets do
-      marksets[class]=remark(marks)
-    end
-  end
-  local done={}
-  local duplicates=check_duplicates and resources.duplicates
-  if duplicates and not next(duplicates) then
-    duplicates=false
-  end
-  local function recover(cover) 
-    for i=1,#cover do
-      local c=cover[i]
-      if not done[c] then
-        local t={}
-        for k,v in next,c do
-          t[indices[k]]=v
-        end
-        cover[i]=t
-        done[c]=d
-      end
-    end
-  end
-  local function recursed(c) 
-    local t={}
-    for g,d in next,c do
-      if type(d)=="table" then
-        t[indices[g]]=recursed(d)
-      else
-        t[g]=indices[d] 
-      end
-    end
-    return t
-  end
-  local function unifythem(sequences)
-    if not sequences then
-      return
-    end
-    for i=1,#sequences do
-      local sequence=sequences[i]
-      local kind=sequence.type
-      local steps=sequence.steps
-      local features=sequence.features
-      if steps then
-        for i=1,#steps do
-          local step=steps[i]
-          if kind=="gsub_single" then
-            local c=step.coverage
-            if c then
-              local t1=done[c]
-              if not t1 then
-                t1={}
-                if duplicates then
-                  for g1,d1 in next,c do
-                    local ug1=indices[g1]
-                    local ud1=indices[d1]
-                    t1[ug1]=ud1
-                    local dg1=duplicates[ug1]
-                    if dg1 then
-                      for u in next,dg1 do
-                        t1[u]=ud1
-                      end
-                    end
-                  end
-                else
-                  for g1,d1 in next,c do
-                    t1[indices[g1]]=indices[d1]
-                  end
-                end
-                done[c]=t1
-              end
-              step.coverage=t1
-            end
-          elseif kind=="gpos_pair" then
-            local c=step.coverage
-            if c then
-              local t1=done[c]
-              if not t1 then
-                t1={}
-                for g1,d1 in next,c do
-                  local t2=done[d1]
-                  if not t2 then
-                    t2={}
-                    for g2,d2 in next,d1 do
-                      t2[indices[g2]]=d2
-                    end
-                    done[d1]=t2
-                  end
-                  t1[indices[g1]]=t2
-                end
-                done[c]=t1
-              end
-              step.coverage=t1
-            end
-          elseif kind=="gsub_ligature" then
-            local c=step.coverage
-            if c then
-              step.coverage=recursed(c)
-            end
-          elseif kind=="gsub_alternate" or kind=="gsub_multiple" then
-            local c=step.coverage
-            if c then
-              local t1=done[c]
-              if not t1 then
-                t1={}
-                if duplicates then
-                  for g1,d1 in next,c do
-                    for i=1,#d1 do
-                      d1[i]=indices[d1[i]]
-                    end
-                    local ug1=indices[g1]
-                    t1[ug1]=d1
-                    local dg1=duplicates[ug1]
-                    if dg1 then
-                      for u in next,dg1 do
-                        t1[u]=copy(d1)
-                      end
-                    end
-                  end
-                else
-                  for g1,d1 in next,c do
-                    for i=1,#d1 do
-                      d1[i]=indices[d1[i]]
-                    end
-                    t1[indices[g1]]=d1
-                  end
-                end
-                done[c]=t1
-              end
-              step.coverage=t1
-            end
-          elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then
-            local c=step.coverage
-            if c then
-              local t1=done[c]
-              if not t1 then
-                t1={}
-                for g1,d1 in next,c do
-                  t1[indices[g1]]=d1
-                end
-                done[c]=t1
-              end
-              step.coverage=t1
-            end
-            local c=step.baseclasses
-            if c then
-              local t1=done[c]
-              if not t1 then
-                for g1,d1 in next,c do
-                  local t2=done[d1]
-                  if not t2 then
-                    t2={}
-                    for g2,d2 in next,d1 do
-                      t2[indices[g2]]=d2
-                    end
-                    done[d1]=t2
-                  end
-                  c[g1]=t2
-                end
-                done[c]=c
-              end
-            end
-          elseif kind=="gpos_single" then
-            local c=step.coverage
-            if c then
-              local t1=done[c]
-              if not t1 then
-                t1={}
-                if duplicates then
-                  for g1,d1 in next,c do
-                    local ug1=indices[g1]
-                    t1[ug1]=d1
-                    local dg1=duplicates[ug1]
-                    if dg1 then
-                      for u in next,dg1 do
-                        t1[u]=d1
-                      end
-                    end
-                  end
-                else
-                  for g1,d1 in next,c do
-                    t1[indices[g1]]=d1
-                  end
-                end
-                done[c]=t1
-              end
-              step.coverage=t1
-            end
-          elseif kind=="gpos_cursive" then
-            local c=step.coverage
-            if c then
-              local t1=done[c]
-              if not t1 then
-                t1={}
-                if duplicates then
-                  for g1,d1 in next,c do
-                    local ug1=indices[g1]
-                    t1[ug1]=d1
-                    local dg1=duplicates[ug1]
-                    if dg1 then
-                      for u in next,dg1 do
-                        t1[u]=copy(d1)
-                      end
-                    end
-                  end
-                else
-                  for g1,d1 in next,c do
-                    t1[indices[g1]]=d1
-                  end
-                end
-                done[c]=t1
-              end
-              step.coverage=t1
-            end
-          end
-          local rules=step.rules
-          if rules then
-            for i=1,#rules do
-              local rule=rules[i]
-              local before=rule.before  if before then recover(before) end
-              local after=rule.after  if after  then recover(after)  end
-              local current=rule.current if current then recover(current) end
-              local replacements=rule.replacements
-              if replacements then
-                if not done[replacements] then
-                  local r={}
-                  for k,v in next,replacements do
-                    r[indices[k]]=indices[v]
-                  end
-                  rule.replacements=r
-                  done[replacements]=r
-                end
-              end
-            end
-          end
-        end
-      end
-    end
-  end
-  unifythem(resources.sequences)
-  unifythem(resources.sublookups)
-end
-local function copyduplicates(fontdata)
-  if check_duplicates then
-    local descriptions=fontdata.descriptions
-    local resources=fontdata.resources
-    local duplicates=resources.duplicates
-    if check_soft_hyphen then
-      local ds=descriptions[0xAD]
-      if not ds or ds.width==0 then
-        if ds then
-          descriptions[0xAD]=nil
-          report("patching soft hyphen")
-        else
-          report("adding soft hyphen")
-        end
-        if not duplicates then
-          duplicates={}
-          resources.duplicates=duplicates
-        end
-        local dh=duplicates[0x2D]
-        if dh then
-          dh[#dh+1]={ [0xAD]=true }
-        else
-          duplicates[0x2D]={ [0xAD]=true }
-        end
-      end
-    end
-    if duplicates then
-      for u,d in next,duplicates do
-        local du=descriptions[u]
-        if du then
-          local t={ f_character_y(u),"@",f_index(du.index),"->" }
-          local n=0
-          local m=25
-          for u in next,d do
-            if descriptions[u] then
-              if n<m then
-                t[n+4]=f_character_n(u)
-              end
-            else
-              local c=copy(du)
-              c.unicode=u 
-              descriptions[u]=c
-              if n<m then
-                t[n+4]=f_character_y(u)
-              end
-            end
-            n=n+1
-          end
-          if n<=m then
-            report("duplicates: %i : % t",n,t)
-          else
-            report("duplicates: %i : % t ...",n,t)
-          end
-        else
-        end
-      end
-    end
-  end
-end
-local ignore={ 
-  ["notdef"]=true,
-  [".notdef"]=true,
-  ["null"]=true,
-  [".null"]=true,
-  ["nonmarkingreturn"]=true,
-}
-local function checklookups(fontdata,missing,nofmissing)
-  local descriptions=fontdata.descriptions
-  local resources=fontdata.resources
-  if missing and nofmissing and nofmissing<=0 then
-    return
-  end
-  local singles={}
-  local alternates={}
-  local ligatures={}
-  if not missing then
-    missing={}
-    nofmissing=0
-    for u,d in next,descriptions do
-      if not d.unicode then
-        nofmissing=nofmissing+1
-        missing[u]=true
-      end
-    end
-  end
-  local function collectthem(sequences)
-    if not sequences then
-      return
-    end
-    for i=1,#sequences do
-      local sequence=sequences[i]
-      local kind=sequence.type
-      local steps=sequence.steps
-      if steps then
-        for i=1,#steps do
-          local step=steps[i]
-          if kind=="gsub_single" then
-            local c=step.coverage
-            if c then
-              singles[#singles+1]=c
-            end
-          elseif kind=="gsub_alternate" then
-            local c=step.coverage
-            if c then
-              alternates[#alternates+1]=c
-            end
-          elseif kind=="gsub_ligature" then
-            local c=step.coverage
-            if c then
-              ligatures[#ligatures+1]=c
-            end
-          end
-        end
-      end
-    end
-  end
-  collectthem(resources.sequences)
-  collectthem(resources.sublookups)
-  local loops=0
-  while true do
-    loops=loops+1
-    local old=nofmissing
-    for i=1,#singles do
-      local c=singles[i]
-      for g1,g2 in next,c do
-        if missing[g1] then
-          local u2=descriptions[g2].unicode
-          if u2 then
-            missing[g1]=false
-            descriptions[g1].unicode=u2
-            nofmissing=nofmissing-1
-          end
-        end
-        if missing[g2] then
-          local u1=descriptions[g1].unicode
-          if u1 then
-            missing[g2]=false
-            descriptions[g2].unicode=u1
-            nofmissing=nofmissing-1
-          end
-        end
-      end
-    end
-    for i=1,#alternates do
-      local c=alternates[i]
-      for g1,d1 in next,c do
-        if missing[g1] then
-          for i=1,#d1 do
-            local g2=d1[i]
-            local u2=descriptions[g2].unicode
-            if u2 then
-              missing[g1]=false
-              descriptions[g1].unicode=u2
-              nofmissing=nofmissing-1
-            end
-          end
-        end
-        if not missing[g1] then
-          for i=1,#d1 do
-            local g2=d1[i]
-            if missing[g2] then
-              local u1=descriptions[g1].unicode
-              if u1 then
-                missing[g2]=false
-                descriptions[g2].unicode=u1
-                nofmissing=nofmissing-1
-              end
-            end
-          end
-        end
-      end
-    end
-    if nofmissing<=0 then
-      report("all done in %s loops",loops)
-      return
-    elseif old==nofmissing then
-      break
-    end
-  end
-  local t,n 
-  local function recursed(c)
-    for g,d in next,c do
-      if g~="ligature" then
-        local u=descriptions[g].unicode
-        if u then
-          n=n+1
-          t[n]=u
-          recursed(d)
-          n=n-1
-        end
-      elseif missing[d] then
-        local l={}
-        local m=0
-        for i=1,n do
-          local u=t[i]
-          if type(u)=="table" then
-            for i=1,#u do
-              m=m+1
-              l[m]=u[i]
-            end
-          else
-            m=m+1
-            l[m]=u
-          end
-        end
-        missing[d]=false
-        descriptions[d].unicode=l
-        nofmissing=nofmissing-1
-      end
-    end
-  end
-  if nofmissing>0 then
-    t={}
-    n=0
-    local loops=0
-    while true do
-      loops=loops+1
-      local old=nofmissing
-      for i=1,#ligatures do
-        recursed(ligatures[i])
-      end
-      if nofmissing<=0 then
-        report("all done in %s loops",loops)
-        return
-      elseif old==nofmissing then
-        break
-      end
-    end
-    t=nil
-    n=0
-  end
-  if nofmissing>0 then
-    local done={}
-    for i,r in next,missing do
-      if r then
-        local data=descriptions[i]
-        local name=data and data.name or f_index(i)
-        if not ignore[name] then
-          done[name]=true
-        end
-      end
-    end
-    if next(done) then
-      report("not unicoded: % t",table.sortedkeys(done))
-    end
-  end
-end
-local function unifymissing(fontdata)
-  if not fonts.mappings then
-    require("font-map")
-    require("font-agl")
-  end
-  local unicodes={}
-  local private=fontdata.private
-  local resources=fontdata.resources
-  resources.unicodes=unicodes
-  for unicode,d in next,fontdata.descriptions do
-    if unicode<privateoffset then
-      local name=d.name
-      if name then
-        unicodes[name]=unicode
-      end
-    end
-  end
-  fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
-  resources.unicodes=nil
-end
-local function unifyglyphs(fontdata,usenames)
-  local private=fontdata.private or privateoffset
-  local glyphs=fontdata.glyphs
-  local indices={}
-  local descriptions={}
-  local names=usenames and {}
-  local resources=fontdata.resources
-  local zero=glyphs[0]
-  local zerocode=zero.unicode
-  if not zerocode then
-    zerocode=private
-    zero.unicode=zerocode
-    private=private+1
-  end
-  descriptions[zerocode]=zero
-  if names then
-    local name=glyphs[0].name or f_private(zerocode)
-    indices[0]=name
-    names[name]=zerocode
-  else
-    indices[0]=zerocode
-  end
-  for index=1,#glyphs do
-    local glyph=glyphs[index]
-    local unicode=glyph.unicode 
-    if not unicode then
-      unicode=private
-      if names then
-        local name=glyph.name or f_private(unicode)
-        indices[index]=name
-        names[name]=unicode
-      else
-        indices[index]=unicode
-      end
-      private=private+1
-    elseif descriptions[unicode] then
-      report("assigning private unicode %U to glyph indexed %05X (%C)",private,index,unicode)
-      unicode=private
-      if names then
-        local name=glyph.name or f_private(unicode)
-        indices[index]=name
-        names[name]=unicode
-      else
-        indices[index]=unicode
-      end
-      private=private+1
-    else
-      if names then
-        local name=glyph.name or f_unicode(unicode)
-        indices[index]=name
-        names[name]=unicode
-      else
-        indices[index]=unicode
-      end
-    end
-    descriptions[unicode]=glyph
-  end
-  for index=1,#glyphs do
-    local math=glyphs[index].math
-    if math then
-      local list=math.vparts
-      if list then
-        for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
-      end
-      local list=math.hparts
-      if list then
-        for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
-      end
-      local list=math.vvariants
-      if list then
-        for i=1,#list do list[i]=indices[list[i]] end
-      end
-      local list=math.hvariants
-      if list then
-        for i=1,#list do list[i]=indices[list[i]] end
-      end
-    end
-  end
-  local colorpalettes=resources.colorpalettes
-  if colorpalettes then
-    for index=1,#glyphs do
-      local colors=glyphs[index].colors
-      if colors then
-        for i=1,#colors do
-          local c=colors[i]
-          c.slot=indices[c.slot]
-        end
-      end
-    end
-  end
-  fontdata.private=private
-  fontdata.glyphs=nil
-  fontdata.names=names
-  fontdata.descriptions=descriptions
-  fontdata.hashmethod=hashmethod
-  return indices,names
-end
-local p_bogusname=(
-  (P("uni")+P("UNI")+P("Uni")+P("U")+P("u"))*S("Xx")^0*R("09","AF")^1+(P("identity")+P("Identity")+P("IDENTITY"))*R("09","AF")^1+(P("index")+P("Index")+P("INDEX"))*R("09")^1
-)*P(-1)
-local function stripredundant(fontdata)
-  local descriptions=fontdata.descriptions
-  if descriptions then
-    local n=0
-    local c=0
-    for unicode,d in next,descriptions do
-      local name=d.name
-      if name and lpegmatch(p_bogusname,name) then
-        d.name=nil
-        n=n+1
-      end
-      if d.class=="base" then
-        d.class=nil
-        c=c+1
-      end
-    end
-    if n>0 then
-      report("%s bogus names removed (verbose unicode)",n)
-    end
-    if c>0 then
-      report("%s base class tags removed (default is base)",c)
-    end
-  end
-end
-function readers.getcomponents(fontdata) 
-  local resources=fontdata.resources
-  if resources then
-    local sequences=resources.sequences
-    if sequences then
-      local collected={}
-      for i=1,#sequences do
-        local sequence=sequences[i]
-        if sequence.type=="gsub_ligature" then
-          local steps=sequence.steps
-          if steps then
-            local l={}
-            local function traverse(p,k,v)
-              if k=="ligature" then
-                collected[v]={ unpack(l) }
-              else
-                insert(l,k)
-                for k,vv in next,v do
-                  traverse(p,k,vv)
-                end
-                remove(l)
-              end
-            end
-            for i=1,#steps do
-              local coverage=steps[i].coverage
-              if coverage then
-                for k,v in next,coverage do
-                  traverse(k,k,v)
-                end
-              end
-            end
-          end
-        end
-      end
-      if next(collected) then
-        while true do
-          local done=false
-          for k,v in next,collected do
-            for i=1,#v do
-              local vi=v[i]
-              if vi==k then
-                collected[k]=nil
-                break
-              else
-                local c=collected[vi]
-                if c then
-                  done=true
-                  local t={}
-                  local n=i-1
-                  for j=1,n do
-                    t[j]=v[j]
-                  end
-                  for j=1,#c do
-                    n=n+1
-                    t[n]=c[j]
-                  end
-                  for j=i+1,#v do
-                    n=n+1
-                    t[n]=v[j]
-                  end
-                  collected[k]=t
-                  break
-                end
-              end
-            end
-          end
-          if not done then
-            break
-          end
-        end
-        return collected
-      end
-    end
-  end
-end
-readers.unifymissing=unifymissing
-function readers.rehash(fontdata,hashmethod) 
-  if not (fontdata and fontdata.glyphs) then
-    return
-  end
-  if hashmethod=="indices" then
-    fontdata.hashmethod="indices"
-  elseif hashmethod=="names" then
-    fontdata.hashmethod="names"
-    local indices=unifyglyphs(fontdata,true)
-    unifyresources(fontdata,indices)
-    copyduplicates(fontdata)
-    unifymissing(fontdata)
-  else
-    fontdata.hashmethod="unicode"
-    local indices=unifyglyphs(fontdata)
-    unifyresources(fontdata,indices)
-    copyduplicates(fontdata)
-    unifymissing(fontdata)
-    stripredundant(fontdata)
-  end
-end
-function readers.checkhash(fontdata)
-  local hashmethod=fontdata.hashmethod
-  if hashmethod=="unicodes" then
-    fontdata.names=nil 
-  elseif hashmethod=="names" and fontdata.names then
-    unifyresources(fontdata,fontdata.names)
-    copyduplicates(fontdata)
-    fontdata.hashmethod="unicode"
-    fontdata.names=nil 
-  else
-    readers.rehash(fontdata,"unicode")
-  end
-end
-function readers.addunicodetable(fontdata)
-  local resources=fontdata.resources
-  local unicodes=resources.unicodes
-  if not unicodes then
-    local descriptions=fontdata.descriptions
-    if descriptions then
-      unicodes={}
-      resources.unicodes=unicodes
-      for u,d in next,descriptions do
-        local n=d.name
-        if n then
-          unicodes[n]=u
-        end
-      end
-    end
-  end
-end
-local concat,sort=table.concat,table.sort
-local next,type,tostring=next,type,tostring
-local criterium=1
-local threshold=0
-local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end)
-local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
-local report_otf=logs.reporter("fonts","otf loading")
-local function tabstr_normal(t)
-  local s={}
-  local n=0
-  for k,v in next,t do
-    n=n+1
-    if type(v)=="table" then
-      s[n]=k..">"..tabstr_normal(v)
-    elseif v==true then
-      s[n]=k.."+" 
-    elseif v then
-      s[n]=k.."="..v
-    else
-      s[n]=k.."-" 
-    end
-  end
-  if n==0 then
-    return ""
-  elseif n==1 then
-    return s[1]
-  else
-    sort(s) 
-    return concat(s,",")
-  end
-end
-local function tabstr_flat(t)
-  local s={}
-  local n=0
-  for k,v in next,t do
-    n=n+1
-    s[n]=k.."="..v
-  end
-  if n==0 then
-    return ""
-  elseif n==1 then
-    return s[1]
-  else
-    sort(s) 
-    return concat(s,",")
-  end
-end
-local function tabstr_mixed(t) 
-  local s={}
-  local n=#t
-  if n==0 then
-    return ""
-  elseif n==1 then
-    local k=t[1]
-    if k==true then
-      return "++" 
-    elseif k==false then
-      return "--" 
-    else
-      return tostring(k) 
-    end
-  else
-    for i=1,n do
-      local k=t[i]
-      if k==true then
-        s[i]="++" 
-      elseif k==false then
-        s[i]="--" 
-      else
-        s[i]=k 
-      end
-    end
-    return concat(s,",")
-  end
-end
-local function tabstr_boolean(t)
-  local s={}
-  local n=0
-  for k,v in next,t do
-    n=n+1
-    if v then
-      s[n]=k.."+"
-    else
-      s[n]=k.."-"
-    end
-  end
-  if n==0 then
-    return ""
-  elseif n==1 then
-    return s[1]
-  else
-    sort(s) 
-    return concat(s,",")
-  end
-end
-function readers.pack(data)
-  if data then
-    local h,t,c={},{},{}
-    local hh,tt,cc={},{},{}
-    local nt,ntt=0,0
-    local function pack_normal(v)
-      local tag=tabstr_normal(v)
-      local ht=h[tag]
-      if ht then
-        c[ht]=c[ht]+1
-        return ht
-      else
-        nt=nt+1
-        t[nt]=v
-        h[tag]=nt
-        c[nt]=1
-        return nt
-      end
-    end
-    local function pack_flat(v)
-      local tag=tabstr_flat(v)
-      local ht=h[tag]
-      if ht then
-        c[ht]=c[ht]+1
-        return ht
-      else
-        nt=nt+1
-        t[nt]=v
-        h[tag]=nt
-        c[nt]=1
-        return nt
-      end
-    end
-    local function pack_boolean(v)
-      local tag=tabstr_boolean(v)
-      local ht=h[tag]
-      if ht then
-        c[ht]=c[ht]+1
-        return ht
-      else
-        nt=nt+1
-        t[nt]=v
-        h[tag]=nt
-        c[nt]=1
-        return nt
-      end
-    end
-    local function pack_indexed(v)
-      local tag=concat(v," ")
-      local ht=h[tag]
-      if ht then
-        c[ht]=c[ht]+1
-        return ht
-      else
-        nt=nt+1
-        t[nt]=v
-        h[tag]=nt
-        c[nt]=1
-        return nt
-      end
-    end
-    local function pack_mixed(v)
-      local tag=tabstr_mixed(v)
-      local ht=h[tag]
-      if ht then
-        c[ht]=c[ht]+1
-        return ht
-      else
-        nt=nt+1
-        t[nt]=v
-        h[tag]=nt
-        c[nt]=1
-        return nt
-      end
-    end
-    local function pack_final(v)
-      if c[v]<=criterium then
-        return t[v]
-      else
-        local hv=hh[v]
-        if hv then
-          return hv
-        else
-          ntt=ntt+1
-          tt[ntt]=t[v]
-          hh[v]=ntt
-          cc[ntt]=c[v]
-          return ntt
-        end
-      end
-    end
-    local function success(stage,pass)
-      if nt==0 then
-        if trace_loading or trace_packing then
-          report_otf("pack quality: nothing to pack")
-        end
-        return false
-      elseif nt>=threshold then
-        local one,two,rest=0,0,0
-        if pass==1 then
-          for k,v in next,c do
-            if v==1 then
-              one=one+1
-            elseif v==2 then
-              two=two+1
-            else
-              rest=rest+1
-            end
-          end
-        else
-          for k,v in next,cc do
-            if v>20 then
-              rest=rest+1
-            elseif v>10 then
-              two=two+1
-            else
-              one=one+1
-            end
-          end
-          data.tables=tt
-        end
-        if trace_loading or trace_packing then
-          report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)",
-            stage,pass,one+two+rest,one,two,rest,criterium)
-        end
-        return true
-      else
-        if trace_loading or trace_packing then
-          report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)",
-            stage,pass,nt,threshold)
-        end
-        return false
-      end
-    end
-    local function packers(pass)
-      if pass==1 then
-        return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed
-      else
-        return pack_final,pack_final,pack_final,pack_final,pack_final
-      end
-    end
-    local resources=data.resources
-    local sequences=resources.sequences
-    local sublookups=resources.sublookups
-    local features=resources.features
-    local palettes=resources.colorpalettes
-    local chardata=characters and characters.data
-    local descriptions=data.descriptions or data.glyphs
-    if not descriptions then
-      return
-    end
-    for pass=1,2 do
-      if trace_packing then
-        report_otf("start packing: stage 1, pass %s",pass)
-      end
-      local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed=packers(pass)
-      for unicode,description in next,descriptions do
-        local boundingbox=description.boundingbox
-        if boundingbox then
-          description.boundingbox=pack_indexed(boundingbox)
-        end
-        local math=description.math
-        if math then
-          local kerns=math.kerns
-          if kerns then
-            for tag,kern in next,kerns do
-              kerns[tag]=pack_normal(kern)
-            end
-          end
-        end
-      end
-      local function packthem(sequences)
-        for i=1,#sequences do
-          local sequence=sequences[i]
-          local kind=sequence.type
-          local steps=sequence.steps
-          local order=sequence.order
-          local features=sequence.features
-          local flags=sequence.flags
-          if steps then
-            for i=1,#steps do
-              local step=steps[i]
-              if kind=="gpos_pair" then
-                local c=step.coverage
-                if c then
-                  if step.format=="kern" then
-                    for g1,d1 in next,c do
-                      c[g1]=pack_normal(d1)
-                    end
-                  else
-                    for g1,d1 in next,c do
-                      for g2,d2 in next,d1 do
-                        local f=d2[1] if f then d2[1]=pack_indexed(f) end
-                        local s=d2[2] if s then d2[2]=pack_indexed(s) end
-                      end
-                    end
-                  end
-                end
-              elseif kind=="gpos_single" then
-                local c=step.coverage
-                if c then
-                  if step.format=="kern" then
-                    step.coverage=pack_normal(c)
-                  else
-                    for g1,d1 in next,c do
-                      c[g1]=pack_indexed(d1)
-                    end
-                  end
-                end
-              elseif kind=="gpos_cursive" then
-                local c=step.coverage
-                if c then
-                  for g1,d1 in next,c do
-                    local f=d1[2] if f then d1[2]=pack_indexed(f) end
-                    local s=d1[3] if s then d1[3]=pack_indexed(s) end
-                  end
-                end
-              elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
-                local c=step.baseclasses
-                if c then
-                  for g1,d1 in next,c do
-                    for g2,d2 in next,d1 do
-                      d1[g2]=pack_indexed(d2)
-                    end
-                  end
-                end
-                local c=step.coverage
-                if c then
-                  for g1,d1 in next,c do
-                    d1[2]=pack_indexed(d1[2])
-                  end
-                end
-              elseif kind=="gpos_mark2ligature" then
-                local c=step.baseclasses
-                if c then
-                  for g1,d1 in next,c do
-                    for g2,d2 in next,d1 do
-                      for g3,d3 in next,d2 do
-                        d2[g3]=pack_indexed(d3)
-                      end
-                    end
-                  end
-                end
-                local c=step.coverage
-                if c then
-                  for g1,d1 in next,c do
-                    d1[2]=pack_indexed(d1[2])
-                  end
-                end
-              end
-              local rules=step.rules
-              if rules then
-                for i=1,#rules do
-                  local rule=rules[i]
-                  local r=rule.before    if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
-                  local r=rule.after    if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
-                  local r=rule.current   if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
-                  local r=rule.lookups   if r then rule.lookups=pack_mixed (r)  end
-                  local r=rule.replacements if r then rule.replacements=pack_flat  (r)  end
-                end
-              end
-            end
-          end
-          if order then
-            sequence.order=pack_indexed(order)
-          end
-          if features then
-            for script,feature in next,features do
-              features[script]=pack_normal(feature)
-            end
-          end
-          if flags then
-            sequence.flags=pack_normal(flags)
-          end
-        end
-      end
-      if sequences then
-        packthem(sequences)
-      end
-      if sublookups then
-        packthem(sublookups)
-      end
-      if features then
-        for k,list in next,features do
-          for feature,spec in next,list do
-            list[feature]=pack_normal(spec)
-          end
-        end
-      end
-      if palettes then
-        for i=1,#palettes do
-          local p=palettes[i]
-          for j=1,#p do
-            p[j]=pack_indexed(p[j])
-          end
-        end
-      end
-      if not success(1,pass) then
-        return
-      end
-    end
-    if nt>0 then
-      for pass=1,2 do
-        if trace_packing then
-          report_otf("start packing: stage 2, pass %s",pass)
-        end
-        local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed=packers(pass)
-        for unicode,description in next,descriptions do
-          local math=description.math
-          if math then
-            local kerns=math.kerns
-            if kerns then
-              math.kerns=pack_normal(kerns)
-            end
-          end
-        end
-        local function packthem(sequences)
-          for i=1,#sequences do
-            local sequence=sequences[i]
-            local kind=sequence.type
-            local steps=sequence.steps
-            local features=sequence.features
-            if steps then
-              for i=1,#steps do
-                local step=steps[i]
-                if kind=="gpos_pair" then
-                  local c=step.coverage
-                  if c then
-                    if step.format=="kern" then
-                    else
-                      for g1,d1 in next,c do
-                        for g2,d2 in next,d1 do
-                          d1[g2]=pack_normal(d2)
-                        end
-                      end
-                    end
-                  end
-                end
-                local rules=step.rules
-                if rules then
-                  for i=1,#rules do
-                    local rule=rules[i]
-                    local r=rule.before if r then rule.before=pack_normal(r) end
-                    local r=rule.after  if r then rule.after=pack_normal(r) end
-                    local r=rule.current if r then rule.current=pack_normal(r) end
-                  end
-                end
-              end
-            end
-            if features then
-              sequence.features=pack_normal(features)
-            end
-          end
-        end
-        if sequences then
-          packthem(sequences)
-        end
-        if sublookups then
-          packthem(sublookups)
-        end
-        if not success(2,pass) then
-        end
-      end
-      for pass=1,2 do
-        if trace_packing then
-          report_otf("start packing: stage 3, pass %s",pass)
-        end
-        local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed=packers(pass)
-        local function packthem(sequences)
-          for i=1,#sequences do
-            local sequence=sequences[i]
-            local kind=sequence.type
-            local steps=sequence.steps
-            local features=sequence.features
-            if steps then
-              for i=1,#steps do
-                local step=steps[i]
-                if kind=="gpos_pair" then
-                  local c=step.coverage
-                  if c then
-                    if step.format=="kern" then
-                    else
-                      for g1,d1 in next,c do
-                        c[g1]=pack_normal(d1)
-                      end
-                    end
-                  end
-                end
-              end
-            end
-          end
-        end
-        if sequences then
-          packthem(sequences)
-        end
-        if sublookups then
-          packthem(sublookups)
-        end
-      end
-    end
-  end
-end
-local unpacked_mt={
-  __index=function(t,k)
-      t[k]=false
-      return k 
-    end
-}
-function readers.unpack(data)
-  if data then
-    local tables=data.tables
-    if tables then
-      local resources=data.resources
-      local descriptions=data.descriptions or data.glyphs
-      local sequences=resources.sequences
-      local sublookups=resources.sublookups
-      local features=resources.features
-      local palettes=resources.colorpalettes
-      local unpacked={}
-      setmetatable(unpacked,unpacked_mt)
-      for unicode,description in next,descriptions do
-        local tv=tables[description.boundingbox]
-        if tv then
-          description.boundingbox=tv
-        end
-        local math=description.math
-        if math then
-          local kerns=math.kerns
-          if kerns then
-            local tm=tables[kerns]
-            if tm then
-              math.kerns=tm
-              kerns=unpacked[tm]
-            end
-            if kerns then
-              for k,kern in next,kerns do
-                local tv=tables[kern]
-                if tv then
-                  kerns[k]=tv
-                end
-              end
-            end
-          end
-        end
-      end
-      local function unpackthem(sequences)
-        for i=1,#sequences do
-          local sequence=sequences[i]
-          local kind=sequence.type
-          local steps=sequence.steps
-          local order=sequence.order
-          local features=sequence.features
-          local flags=sequence.flags
-          local markclass=sequence.markclass
-          if steps then
-            for i=1,#steps do
-              local step=steps[i]
-              if kind=="gpos_pair" then
-                local c=step.coverage
-                if c then
-                  if step.format=="kern" then
-                    for g1,d1 in next,c do
-                      local tv=tables[d1]
-                      if tv then
-                        c[g1]=tv
-                      end
-                    end
-                  else
-                    for g1,d1 in next,c do
-                      local tv=tables[d1]
-                      if tv then
-                        c[g1]=tv
-                        d1=tv
-                      end
-                      for g2,d2 in next,d1 do
-                        local tv=tables[d2]
-                        if tv then
-                          d1[g2]=tv
-                          d2=tv
-                        end
-                        local f=tables[d2[1]] if f then d2[1]=f end
-                        local s=tables[d2[2]] if s then d2[2]=s end
-                      end
-                    end
-                  end
-                end
-              elseif kind=="gpos_single" then
-                local c=step.coverage
-                if c then
-                  if step.format=="kern" then
-                    local tv=tables[c]
-                    if tv then
-                      step.coverage=tv
-                    end
-                  else
-                    for g1,d1 in next,c do
-                      local tv=tables[d1]
-                      if tv then
-                        c[g1]=tv
-                      end
-                    end
-                  end
-                end
-              elseif kind=="gpos_cursive" then
-                local c=step.coverage
-                if c then
-                  for g1,d1 in next,c do
-                    local f=tables[d1[2]] if f then d1[2]=f end
-                    local s=tables[d1[3]] if s then d1[3]=s end
-                  end
-                end
-              elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
-                local c=step.baseclasses
-                if c then
-                  for g1,d1 in next,c do
-                    for g2,d2 in next,d1 do
-                      local tv=tables[d2]
-                      if tv then
-                        d1[g2]=tv
-                      end
-                    end
-                  end
-                end
-                local c=step.coverage
-                if c then
-                  for g1,d1 in next,c do
-                    local tv=tables[d1[2]]
-                    if tv then
-                      d1[2]=tv
-                    end
-                  end
-                end
-              elseif kind=="gpos_mark2ligature" then
-                local c=step.baseclasses
-                if c then
-                  for g1,d1 in next,c do
-                    for g2,d2 in next,d1 do
-                      for g3,d3 in next,d2 do
-                        local tv=tables[d2[g3]]
-                        if tv then
-                          d2[g3]=tv
-                        end
-                      end
-                    end
-                  end
-                end
-                local c=step.coverage
-                if c then
-                  for g1,d1 in next,c do
-                    local tv=tables[d1[2]]
-                    if tv then
-                      d1[2]=tv
-                    end
-                  end
-                end
-              end
-              local rules=step.rules
-              if rules then
-                for i=1,#rules do
-                  local rule=rules[i]
-                  local before=rule.before
-                  if before then
-                    local tv=tables[before]
-                    if tv then
-                      rule.before=tv
-                      before=tv
-                    end
-                    for i=1,#before do
-                      local tv=tables[before[i]]
-                      if tv then
-                        before[i]=tv
-                      end
-                    end
-                  end
-                  local after=rule.after
-                  if after then
-                    local tv=tables[after]
-                    if tv then
-                      rule.after=tv
-                      after=tv
-                    end
-                    for i=1,#after do
-                      local tv=tables[after[i]]
-                      if tv then
-                        after[i]=tv
-                      end
-                    end
-                  end
-                  local current=rule.current
-                  if current then
-                    local tv=tables[current]
-                    if tv then
-                      rule.current=tv
-                      current=tv
-                    end
-                    for i=1,#current do
-                      local tv=tables[current[i]]
-                      if tv then
-                        current[i]=tv
-                      end
-                    end
-                  end
-                  local lookups=rule.lookups
-                  if lookups then
-                    local tv=tables[lookups]
-                    if tv then
-                      rule.lookups=tv
-                    end
-                  end
-                  local replacements=rule.replacements
-                  if replacements then
-                    local tv=tables[replacements]
-                    if tv then
-                      rule.replacements=tv
-                    end
-                  end
-                end
-              end
-            end
-          end
-          if features then
-            local tv=tables[features]
-            if tv then
-              sequence.features=tv
-              features=tv
-            end
-            for script,feature in next,features do
-              local tv=tables[feature]
-              if tv then
-                features[script]=tv
-              end
-            end
-          end
-          if order then
-            local tv=tables[order]
-            if tv then
-              sequence.order=tv
-            end
-          end
-          if flags then
-            local tv=tables[flags]
-            if tv then
-              sequence.flags=tv
-            end
-          end
-        end
-      end
-      if sequences then
-        unpackthem(sequences)
-      end
-      if sublookups then
-        unpackthem(sublookups)
-      end
-      if features then
-        for k,list in next,features do
-          for feature,spec in next,list do
-            local tv=tables[spec]
-            if tv then
-              list[feature]=tv
-            end
-          end
-        end
-      end
-      if palettes then
-        for i=1,#palettes do
-          local p=palettes[i]
-          for j=1,#p do
-            local tv=tables[p[j]]
-            if tv then
-              p[j]=tv
-            end
-          end
-        end
-      end
-      data.tables=nil
-    end
-  end
-end
-local mt={
-  __index=function(t,k) 
-    if k=="height" then
-      local ht=t.boundingbox[4]
-      return ht<0 and 0 or ht
-    elseif k=="depth" then
-      local dp=-t.boundingbox[2]
-      return dp<0 and 0 or dp
-    elseif k=="width" then
-      return 0
-    elseif k=="name" then 
-      return forcenotdef and ".notdef"
-    end
-  end
-}
-local function sameformat(sequence,steps,first,nofsteps,kind)
-  return true
-end
-local function mergesteps_1(lookup,strict)
-  local steps=lookup.steps
-  local nofsteps=lookup.nofsteps
-  local first=steps[1]
-  if strict then
-    local f=first.format
-    for i=2,nofsteps do
-      if steps[i].format~=f then
-        report("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
-        return 0
-      end
-    end
-  end
-  report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
-  local target=first.coverage
-  for i=2,nofsteps do
-    for k,v in next,steps[i].coverage do
-      if not target[k] then
-        target[k]=v
-      end
-    end
-  end
-  lookup.nofsteps=1
-  lookup.merged=true
-  lookup.steps={ first }
-  return nofsteps-1
-end
-local function mergesteps_2(lookup,strict) 
-  local steps=lookup.steps
-  local nofsteps=lookup.nofsteps
-  local first=steps[1]
-  if strict then
-    local f=first.format
-    for i=2,nofsteps do
-      if steps[i].format~=f then
-        report("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
-        return 0
-      end
-    end
-  end
-  report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
-  local target=first.coverage
-  for i=2,nofsteps do
-    for k,v in next,steps[i].coverage do
-      local tk=target[k]
-      if tk then
-        for k,v in next,v do
-          if not tk[k] then
-            tk[k]=v
-          end
-        end
-      else
-        target[k]=v
-      end
-    end
-  end
-  lookup.nofsteps=1
-  lookup.steps={ first }
-  return nofsteps-1
-end
-local function mergesteps_3(lookup,strict) 
-  local steps=lookup.steps
-  local nofsteps=lookup.nofsteps
-  local first=steps[1]
-  report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
-  local baseclasses={}
-  local coverage={}
-  local used={}
-  for i=1,nofsteps do
-    local offset=i*10
-    local step=steps[i]
-    for k,v in sortedhash(step.baseclasses) do
-      baseclasses[offset+k]=v
-    end
-    for k,v in next,step.coverage do
-      local tk=coverage[k]
-      if tk then
-        for k,v in next,v do
-          if not tk[k] then
-            tk[k]=v
-            local c=offset+v[1]
-            v[1]=c
-            if not used[c] then
-              used[c]=true
-            end
-          end
-        end
-      else
-        coverage[k]=v
-        local c=offset+v[1]
-        v[1]=c
-        if not used[c] then
-          used[c]=true
-        end
-      end
-    end
-  end
-  for k,v in next,baseclasses do
-    if not used[k] then
-      baseclasses[k]=nil
-      report("discarding not used baseclass %i",k)
-    end
-  end
-  first.baseclasses=baseclasses
-  first.coverage=coverage
-  lookup.nofsteps=1
-  lookup.steps={ first }
-  return nofsteps-1
-end
-local function nested(old,new)
-  for k,v in next,old do
-    if k=="ligature" then
-      if not new.ligature then
-        new.ligature=v
-      end
-    else
-      local n=new[k]
-      if n then
-        nested(v,n)
-      else
-        new[k]=v
-      end
-    end
-  end
-end
-local function mergesteps_4(lookup) 
-  local steps=lookup.steps
-  local nofsteps=lookup.nofsteps
-  local first=steps[1]
-  report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
-  local target=first.coverage
-  for i=2,nofsteps do
-    for k,v in next,steps[i].coverage do
-      local tk=target[k]
-      if tk then
-        nested(v,tk)
-      else
-        target[k]=v
-      end
-    end
-  end
-  lookup.nofsteps=1
-  lookup.steps={ first }
-  return nofsteps-1
-end
-local function checkkerns(lookup)
-  local steps=lookup.steps
-  local nofsteps=lookup.nofsteps
-  for i=1,nofsteps do
-    local step=steps[i]
-    if step.format=="pair" then
-      local coverage=step.coverage
-      local kerns=true
-      for g1,d1 in next,coverage do
-        if d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then
-          kerns=false
-          break
-        end
-      end
-      if kerns then
-        report("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
-        for g1,d1 in next,coverage do
-          coverage[g1]=d1[3]
-        end
-        step.format="kern"
-      end
-    end
-  end
-end
-local function checkpairs(lookup)
-  local steps=lookup.steps
-  local nofsteps=lookup.nofsteps
-  local kerned=0
-  for i=1,nofsteps do
-    local step=steps[i]
-    if step.format=="pair" then
-      local coverage=step.coverage
-      local kerns=true
-      for g1,d1 in next,coverage do
-        for g2,d2 in next,d1 do
-          if d2[2] then
-            kerns=false
-            break
-          else
-            local v=d2[1]
-            if v[1]~=0 or v[2]~=0 or v[4]~=0 then
-              kerns=false
-              break
-            end
-          end
-        end
-      end
-      if kerns then
-        report("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
-        for g1,d1 in next,coverage do
-          for g2,d2 in next,d1 do
-            d1[g2]=d2[1][3]
-          end
-        end
-        step.format="kern"
-        kerned=kerned+1
-      end
-    end
-  end
-  return kerned
-end
-function readers.compact(data)
-  if not data or data.compacted then
-    return
-  else
-    data.compacted=true
-  end
-  local resources=data.resources
-  local merged=0
-  local kerned=0
-  local allsteps=0
-  local function compact(what)
-    local lookups=resources[what]
-    if lookups then
-      for i=1,#lookups do
-        local lookup=lookups[i]
-        local nofsteps=lookup.nofsteps
-        allsteps=allsteps+nofsteps
-        if nofsteps>1 then
-          local kind=lookup.type
-          if kind=="gsub_single" or kind=="gsub_alternate" or kind=="gsub_multiple" then
-            merged=merged+mergesteps_1(lookup)
-          elseif kind=="gsub_ligature" then
-            merged=merged+mergesteps_4(lookup)
-          elseif kind=="gpos_single" then
-            merged=merged+mergesteps_1(lookup,true)
-            checkkerns(lookup)
-          elseif kind=="gpos_pair" then
-            merged=merged+mergesteps_2(lookup,true)
-            kerned=kerned+checkpairs(lookup)
-          elseif kind=="gpos_cursive" then
-            merged=merged+mergesteps_2(lookup)
-          elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then
-            merged=merged+mergesteps_3(lookup)
-          end
-        end
-      end
-    else
-      report("no lookups in %a",what)
-    end
-  end
-  compact("sequences")
-  compact("sublookups")
-  if merged>0 then
-    report("%i steps of %i removed due to merging",merged,allsteps)
-  end
-  if kerned>0 then
-    report("%i steps of %i steps turned from pairs into kerns",kerned,allsteps)
-  end
-end
-function readers.expand(data)
-  if not data or data.expanded then
-    return
-  else
-    data.expanded=true
-  end
-  local resources=data.resources
-  local sublookups=resources.sublookups
-  local sequences=resources.sequences 
-  local markclasses=resources.markclasses
-  local descriptions=data.descriptions
-  if descriptions then
-    local defaultwidth=resources.defaultwidth or 0
-    local defaultheight=resources.defaultheight or 0
-    local defaultdepth=resources.defaultdepth or 0
-    local basename=trace_markwidth and file.basename(resources.filename)
-    for u,d in next,descriptions do
-      local bb=d.boundingbox
-      local wd=d.width
-      if not wd then
-        d.width=defaultwidth
-      elseif trace_markwidth and wd~=0 and d.class=="mark" then
-        report("mark %a with width %b found in %a",d.name or "<noname>",wd,basename)
-      end
-      if bb then
-        local ht=bb[4]
-        local dp=-bb[2]
-        if ht==0 or ht<0 then
-        else
-          d.height=ht
-        end
-        if dp==0 or dp<0 then
-        else
-          d.depth=dp
-        end
-      end
-    end
-  end
-  local function expandlookups(sequences)
-    if sequences then
-      for i=1,#sequences do
-        local sequence=sequences[i]
-        local steps=sequence.steps
-        if steps then
-          local kind=sequence.type
-          local markclass=sequence.markclass
-          if markclass then
-            if not markclasses then
-              report_warning("missing markclasses")
-              sequence.markclass=false
-            else
-              sequence.markclass=markclasses[markclass]
-            end
-          end
-          for i=1,sequence.nofsteps do
-            local step=steps[i]
-            local baseclasses=step.baseclasses
-            if baseclasses then
-              local coverage=step.coverage
-              for k,v in next,coverage do
-                v[1]=baseclasses[v[1]] 
-              end
-            elseif kind=="gpos_cursive" then
-              local coverage=step.coverage
-              for k,v in next,coverage do
-                v[1]=coverage 
-              end
-            end
-            local rules=step.rules
-            if rules then
-              local rulehash={}
-              local rulesize=0
-              local coverage={}
-              local lookuptype=sequence.type
-              step.coverage=coverage 
-              for nofrules=1,#rules do
-                local rule=rules[nofrules]
-                local current=rule.current
-                local before=rule.before
-                local after=rule.after
-                local replacements=rule.replacements or false
-                local sequence={}
-                local nofsequences=0
-                if before then
-                  for n=1,#before do
-                    nofsequences=nofsequences+1
-                    sequence[nofsequences]=before[n]
-                  end
-                end
-                local start=nofsequences+1
-                for n=1,#current do
-                  nofsequences=nofsequences+1
-                  sequence[nofsequences]=current[n]
-                end
-                local stop=nofsequences
-                if after then
-                  for n=1,#after do
-                    nofsequences=nofsequences+1
-                    sequence[nofsequences]=after[n]
-                  end
-                end
-                local lookups=rule.lookups or false
-                local subtype=nil
-                if lookups then
-                  for k,v in next,lookups do
-                    local lookup=sublookups[v]
-                    if lookup then
-                      lookups[k]=lookup
-                      if not subtype then
-                        subtype=lookup.type
-                      end
-                    else
-                    end
-                  end
-                end
-                if sequence[1] then 
-                  rulesize=rulesize+1
-                  rulehash[rulesize]={
-                    nofrules,
-                    lookuptype,
-                    sequence,
-                    start,
-                    stop,
-                    lookups,
-                    replacements,
-                    subtype,
-                  }
-                  for unic in next,sequence[start] do
-                    local cu=coverage[unic]
-                    if not cu then
-                      coverage[unic]=rulehash 
-                    end
-                  end
-                end
-              end
-            end
-          end
-        end
-      end
-    end
-  end
-  expandlookups(sequences)
-  expandlookups(sublookups)
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-oup”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-otl” 2e7c8d9a331c46826211bd507f8e488a] ---
-
-if not modules then modules={} end modules ['font-otl']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files",
-}
-local gmatch,find,match,lower,strip=string.gmatch,string.find,string.match,string.lower,string.strip
-local type,next,tonumber,tostring,unpack=type,next,tonumber,tostring,unpack
-local abs=math.abs
-local derivetable=table.derive
-local formatters=string.formatters
-local setmetatableindex=table.setmetatableindex
-local allocate=utilities.storage.allocate
-local registertracker=trackers.register
-local registerdirective=directives.register
-local starttiming=statistics.starttiming
-local stoptiming=statistics.stoptiming
-local elapsedtime=statistics.elapsedtime
-local findbinfile=resolvers.findbinfile
-local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end)
-local trace_features=false registertracker("otf.features",function(v) trace_features=v end)
-local trace_defining=false registertracker("fonts.defining",function(v) trace_defining=v end)
-local report_otf=logs.reporter("fonts","otf loading")
-local fonts=fonts
-local otf=fonts.handlers.otf
-otf.version=3.027 
-otf.cache=containers.define("fonts","otl",otf.version,true)
-otf.svgcache=containers.define("fonts","svg",otf.version,true)
-otf.pdfcache=containers.define("fonts","pdf",otf.version,true)
-otf.svgenabled=false
-local otfreaders=otf.readers
-local hashes=fonts.hashes
-local definers=fonts.definers
-local readers=fonts.readers
-local constructors=fonts.constructors
-local otffeatures=constructors.features.otf
-local registerotffeature=otffeatures.register
-local otfenhancers=constructors.enhancers.otf
-local registerotfenhancer=otfenhancers.register
-local forceload=false
-local cleanup=0   
-local syncspace=true
-local forcenotdef=false
-local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes
-local wildcard="*"
-local default="dflt"
-local formats=fonts.formats
-formats.otf="opentype"
-formats.ttf="truetype"
-formats.ttc="truetype"
-registerdirective("fonts.otf.loader.cleanup",function(v) cleanup=tonumber(v) or (v and 1) or 0 end)
-registerdirective("fonts.otf.loader.force",function(v) forceload=v end)
-registerdirective("fonts.otf.loader.syncspace",function(v) syncspace=v end)
-registerdirective("fonts.otf.loader.forcenotdef",function(v) forcenotdef=v end)
-registerotfenhancer("check extra features",function() end) 
-function otf.load(filename,sub,featurefile)
-  local featurefile=nil
-  local base=file.basename(file.removesuffix(filename))
-  local name=file.removesuffix(base)
-  local attr=lfs.attributes(filename)
-  local size=attr and attr.size or 0
-  local time=attr and attr.modification or 0
-  if featurefile then
-    name=name.."@"..file.removesuffix(file.basename(featurefile))
-  end
-  if sub=="" then
-    sub=false
-  end
-  local hash=name
-  if sub then
-    hash=hash.."-"..sub
-  end
-  hash=containers.cleanname(hash)
-  local featurefiles
-  if featurefile then
-    featurefiles={}
-    for s in gmatch(featurefile,"[^,]+") do
-      local name=resolvers.findfile(file.addsuffix(s,'fea'),'fea') or ""
-      if name=="" then
-        report_otf("loading error, no featurefile %a",s)
-      else
-        local attr=lfs.attributes(name)
-        featurefiles[#featurefiles+1]={
-          name=name,
-          size=attr and attr.size or 0,
-          time=attr and attr.modification or 0,
-        }
-      end
-    end
-    if #featurefiles==0 then
-      featurefiles=nil
-    end
-  end
-  local data=containers.read(otf.cache,hash)
-  local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion
-  if forceload then
-    report_otf("forced reload of %a due to hard coded flag",filename)
-    reload=true
-  end
-   if reload then
-    report_otf("loading %a, hash %a",filename,hash)
-    starttiming(otfreaders)
-    data=otfreaders.loadfont(filename,sub or 1)
-    if data then
-      local resources=data.resources
-      local svgshapes=resources.svgshapes
-      if svgshapes then
-        resources.svgshapes=nil
-        if otf.svgenabled then
-          local timestamp=os.date()
-          containers.write(otf.svgcache,hash,{
-            svgshapes=svgshapes,
-            timestamp=timestamp,
-          })
-          data.properties.svg={
-            hash=hash,
-            timestamp=timestamp,
-          }
-        end
-      end
-      otfreaders.compact(data)
-      otfreaders.rehash(data,"unicodes")
-      otfreaders.addunicodetable(data)
-      otfreaders.extend(data)
-      otfreaders.pack(data)
-      report_otf("loading done")
-      report_otf("saving %a in cache",filename)
-      data=containers.write(otf.cache,hash,data)
-      if cleanup>1 then
-        collectgarbage("collect")
-      end
-      stoptiming(otfreaders)
-      if elapsedtime then
-        report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders))
-      end
-      if cleanup>3 then
-        collectgarbage("collect")
-      end
-      data=containers.read(otf.cache,hash) 
-      if cleanup>2 then
-        collectgarbage("collect")
-      end
-    else
-      data=nil
-      report_otf("loading failed due to read error")
-    end
-  end
-  if data then
-    if trace_defining then
-      report_otf("loading from cache using hash %a",hash)
-    end
-    otfreaders.unpack(data)
-    otfreaders.expand(data) 
-    otfreaders.addunicodetable(data)
-    otfenhancers.apply(data,filename,data)
-    if applyruntimefixes then
-      applyruntimefixes(filename,data)
-    end
-    data.metadata.math=data.resources.mathconstants
-  end
-  return data
-end
-function otf.setfeatures(tfmdata,features)
-  local okay=constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf)
-  if okay then
-    return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf)
-  else
-    return {} 
-  end
-end
-local function copytotfm(data,cache_id)
-  if data then
-    local metadata=data.metadata
-    local properties=derivetable(data.properties)
-    local descriptions=derivetable(data.descriptions)
-    local goodies=derivetable(data.goodies)
-    local characters={}
-    local parameters={}
-    local mathparameters={}
-    local resources=data.resources
-    local unicodes=resources.unicodes
-    local spaceunits=500
-    local spacer="space"
-    local designsize=metadata.designsize or 100
-    local minsize=metadata.minsize or designsize
-    local maxsize=metadata.maxsize or designsize
-    local mathspecs=metadata.math
-    if designsize==0 then
-      designsize=100
-      minsize=100
-      maxsize=100
-    end
-    if mathspecs then
-      for name,value in next,mathspecs do
-        mathparameters[name]=value
-      end
-    end
-    for unicode in next,data.descriptions do 
-      characters[unicode]={}
-    end
-    if mathspecs then
-      for unicode,character in next,characters do
-        local d=descriptions[unicode]
-        local m=d.math
-        if m then
-          local italic=m.italic
-          local vitalic=m.vitalic
-          local variants=m.hvariants
-          local parts=m.hparts
-          if variants then
-            local c=character
-            for i=1,#variants do
-              local un=variants[i]
-              c.next=un
-              c=characters[un]
-            end 
-            c.horiz_variants=parts
-          elseif parts then
-            character.horiz_variants=parts
-            italic=m.hitalic
-          end
-          local variants=m.vvariants
-          local parts=m.vparts
-          if variants then
-            local c=character
-            for i=1,#variants do
-              local un=variants[i]
-              c.next=un
-              c=characters[un]
-            end 
-            c.vert_variants=parts
-          elseif parts then
-            character.vert_variants=parts
-          end
-          if italic and italic~=0 then
-            character.italic=italic
-          end
-          if vitalic and vitalic~=0 then
-            character.vert_italic=vitalic
-          end
-          local accent=m.accent 
-          if accent then
-            character.accent=accent
-          end
-          local kerns=m.kerns
-          if kerns then
-            character.mathkerns=kerns
-          end
-        end
-      end
-    end
-    local filename=constructors.checkedfilename(resources)
-    local fontname=metadata.fontname
-    local fullname=metadata.fullname or fontname
-    local psname=fontname or fullname
-    local units=metadata.units or 1000
-    if units==0 then 
-      units=1000 
-      metadata.units=1000
-      report_otf("changing %a units to %a",0,units)
-    end
-    local monospaced=metadata.monospaced
-    local charwidth=metadata.averagewidth 
-    local charxheight=metadata.xheight 
-    local italicangle=metadata.italicangle
-    local hasitalics=metadata.hasitalics
-    properties.monospaced=monospaced
-    properties.hasitalics=hasitalics
-    parameters.italicangle=italicangle
-    parameters.charwidth=charwidth
-    parameters.charxheight=charxheight
-    local space=0x0020
-    local emdash=0x2014
-    if monospaced then
-      if descriptions[space] then
-        spaceunits,spacer=descriptions[space].width,"space"
-      end
-      if not spaceunits and descriptions[emdash] then
-        spaceunits,spacer=descriptions[emdash].width,"emdash"
-      end
-      if not spaceunits and charwidth then
-        spaceunits,spacer=charwidth,"charwidth"
-      end
-    else
-      if descriptions[space] then
-        spaceunits,spacer=descriptions[space].width,"space"
-      end
-      if not spaceunits and descriptions[emdash] then
-        spaceunits,spacer=descriptions[emdash].width/2,"emdash/2"
-      end
-      if not spaceunits and charwidth then
-        spaceunits,spacer=charwidth,"charwidth"
-      end
-    end
-    spaceunits=tonumber(spaceunits) or units/2
-    parameters.slant=0
-    parameters.space=spaceunits      
-    parameters.space_stretch=1*units/2  
-    parameters.space_shrink=1*units/3  
-    parameters.x_height=2*units/5  
-    parameters.quad=units    
-    if spaceunits<2*units/5 then
-    end
-    if italicangle and italicangle~=0 then
-      parameters.italicangle=italicangle
-      parameters.italicfactor=math.cos(math.rad(90+italicangle))
-      parameters.slant=- math.tan(italicangle*math.pi/180)
-    end
-    if monospaced then
-      parameters.space_stretch=0
-      parameters.space_shrink=0
-    elseif syncspace then 
-      parameters.space_stretch=spaceunits/2
-      parameters.space_shrink=spaceunits/3
-    end
-    parameters.extra_space=parameters.space_shrink 
-    if charxheight then
-      parameters.x_height=charxheight
-    else
-      local x=0x0078
-      if x then
-        local x=descriptions[x]
-        if x then
-          parameters.x_height=x.height
-        end
-      end
-    end
-    parameters.designsize=(designsize/10)*65536
-    parameters.minsize=(minsize/10)*65536
-    parameters.maxsize=(maxsize/10)*65536
-    parameters.ascender=abs(metadata.ascender or 0)
-    parameters.descender=abs(metadata.descender or 0)
-    parameters.units=units
-    properties.space=spacer
-    properties.encodingbytes=2
-    properties.format=data.format or formats.otf
-    properties.noglyphnames=true
-    properties.filename=filename
-    properties.fontname=fontname
-    properties.fullname=fullname
-    properties.psname=psname
-    properties.name=filename or fullname
-    return {
-      characters=characters,
-      descriptions=descriptions,
-      parameters=parameters,
-      mathparameters=mathparameters,
-      resources=resources,
-      properties=properties,
-      goodies=goodies,
-    }
-  end
-end
-local converters={
-  woff={
-    cachename="webfonts",
-    action=otf.readers.woff2otf,
-  }
-}
-local function checkconversion(specification)
-  local filename=specification.filename
-  local converter=converters[lower(file.suffix(filename))]
-  if converter then
-    local base=file.basename(filename)
-    local name=file.removesuffix(base)
-    local attr=lfs.attributes(filename)
-    local size=attr and attr.size or 0
-    local time=attr and attr.modification or 0
-    if size>0 then
-      local cleanname=containers.cleanname(name)
-      local cachename=caches.setfirstwritablefile(cleanname,converter.cachename)
-      if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then
-        report_otf("caching font %a in %a",filename,cachename)
-        converter.action(filename,cachename) 
-        lfs.touch(cachename,time,time)
-      end
-      specification.filename=cachename
-    end
-  end
-end
-local function otftotfm(specification)
-  local cache_id=specification.hash
-  local tfmdata=containers.read(constructors.cache,cache_id)
-  if not tfmdata then
-    checkconversion(specification) 
-    local name=specification.name
-    local sub=specification.sub
-    local subindex=specification.subindex
-    local filename=specification.filename
-    local features=specification.features.normal
-    local rawdata=otf.load(filename,sub,features and features.featurefile)
-    if rawdata and next(rawdata) then
-      local descriptions=rawdata.descriptions
-      rawdata.lookuphash={} 
-      tfmdata=copytotfm(rawdata,cache_id)
-      if tfmdata and next(tfmdata) then
-        local features=constructors.checkedfeatures("otf",features)
-        local shared=tfmdata.shared
-        if not shared then
-          shared={}
-          tfmdata.shared=shared
-        end
-        shared.rawdata=rawdata
-        shared.dynamics={}
-        tfmdata.changed={}
-        shared.features=features
-        shared.processes=otf.setfeatures(tfmdata,features)
-      end
-    end
-    containers.write(constructors.cache,cache_id,tfmdata)
-  end
-  return tfmdata
-end
-local function read_from_otf(specification)
-  local tfmdata=otftotfm(specification)
-  if tfmdata then
-    tfmdata.properties.name=specification.name
-    tfmdata.properties.sub=specification.sub
-    tfmdata=constructors.scale(tfmdata,specification)
-    local allfeatures=tfmdata.shared.features or specification.features.normal
-    constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf)
-    constructors.setname(tfmdata,specification) 
-    fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification)
-  end
-  return tfmdata
-end
-local function checkmathsize(tfmdata,mathsize)
-  local mathdata=tfmdata.shared.rawdata.metadata.math
-  local mathsize=tonumber(mathsize)
-  if mathdata then 
-    local parameters=tfmdata.parameters
-    parameters.scriptpercentage=mathdata.ScriptPercentScaleDown
-    parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown
-    parameters.mathsize=mathsize
-  end
-end
-registerotffeature {
-  name="mathsize",
-  description="apply mathsize specified in the font",
-  initializers={
-    base=checkmathsize,
-    node=checkmathsize,
-  }
-}
-function otf.collectlookups(rawdata,kind,script,language)
-  if not kind then
-    return
-  end
-  if not script then
-    script=default
-  end
-  if not language then
-    language=default
-  end
-  local lookupcache=rawdata.lookupcache
-  if not lookupcache then
-    lookupcache={}
-    rawdata.lookupcache=lookupcache
-  end
-  local kindlookup=lookupcache[kind]
-  if not kindlookup then
-    kindlookup={}
-    lookupcache[kind]=kindlookup
-  end
-  local scriptlookup=kindlookup[script]
-  if not scriptlookup then
-    scriptlookup={}
-    kindlookup[script]=scriptlookup
-  end
-  local languagelookup=scriptlookup[language]
-  if not languagelookup then
-    local sequences=rawdata.resources.sequences
-    local featuremap={}
-    local featurelist={}
-    if sequences then
-      for s=1,#sequences do
-        local sequence=sequences[s]
-        local features=sequence.features
-        if features then
-          features=features[kind]
-          if features then
-            features=features[script] or features[wildcard]
-            if features then
-              features=features[language] or features[wildcard]
-              if features then
-                if not featuremap[sequence] then
-                  featuremap[sequence]=true
-                  featurelist[#featurelist+1]=sequence
-                end
-              end
-            end
-          end
-        end
-      end
-      if #featurelist==0 then
-        featuremap,featurelist=false,false
-      end
-    else
-      featuremap,featurelist=false,false
-    end
-    languagelookup={ featuremap,featurelist }
-    scriptlookup[language]=languagelookup
-  end
-  return unpack(languagelookup)
-end
-local function getgsub(tfmdata,k,kind,value)
-  local shared=tfmdata.shared
-  local rawdata=shared and shared.rawdata
-  if rawdata then
-    local sequences=rawdata.resources.sequences
-    if sequences then
-      local properties=tfmdata.properties
-      local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language)
-      if validlookups then
-        for i=1,#lookuplist do
-          local lookup=lookuplist[i]
-          local steps=lookup.steps
-          local nofsteps=lookup.nofsteps
-          for i=1,nofsteps do
-            local coverage=steps[i].coverage
-            if coverage then
-              local found=coverage[k]
-              if found then
-                return found,lookup.type
-              end
-            end
-          end
-        end
-      end
-    end
-  end
-end
-otf.getgsub=getgsub 
-function otf.getsubstitution(tfmdata,k,kind,value)
-  local found,kind=getgsub(tfmdata,k,kind,value)
-  if not found then
-  elseif kind=="gsub_single" then
-    return found
-  elseif kind=="gsub_alternate" then
-    local choice=tonumber(value) or 1 
-    return found[choice] or found[1] or k
-  end
-  return k
-end
-otf.getalternate=otf.getsubstitution
-function otf.getmultiple(tfmdata,k,kind)
-  local found,kind=getgsub(tfmdata,k,kind)
-  if found and kind=="gsub_multiple" then
-    return found
-  end
-  return { k }
-end
-function otf.getkern(tfmdata,left,right,kind)
-  local kerns=getgsub(tfmdata,left,kind or "kern",true) 
-  if kerns then
-    local found=kerns[right]
-    local kind=type(found)
-    if kind=="table" then
-      found=found[1][3] 
-    elseif kind~="number" then
-      found=false
-    end
-    if found then
-      return found*tfmdata.parameters.factor
-    end
-  end
-  return 0
-end
-local function check_otf(forced,specification,suffix)
-  local name=specification.name
-  if forced then
-    name=specification.forcedname 
-  end
-  local fullname=findbinfile(name,suffix) or ""
-  if fullname=="" then
-    fullname=fonts.names.getfilename(name,suffix) or ""
-  end
-  if fullname~="" and not fonts.names.ignoredfile(fullname) then
-    specification.filename=fullname
-    return read_from_otf(specification)
-  end
-end
-local function opentypereader(specification,suffix)
-  local forced=specification.forced or ""
-  if formats[forced] then
-    return check_otf(true,specification,forced)
-  else
-    return check_otf(false,specification,suffix)
-  end
-end
-readers.opentype=opentypereader 
-function readers.otf(specification) return opentypereader(specification,"otf") end
-function readers.ttf(specification) return opentypereader(specification,"ttf") end
-function readers.ttc(specification) return opentypereader(specification,"ttf") end
-function readers.woff(specification)
-  checkconversion(specification)
-  opentypereader(specification,"")
-end
-function otf.scriptandlanguage(tfmdata,attr)
-  local properties=tfmdata.properties
-  return properties.script or "dflt",properties.language or "dflt"
-end
-local function justset(coverage,unicode,replacement)
-  coverage[unicode]=replacement
-end
-otf.coverup={
-  stepkey="steps",
-  actions={
-    chainsubstitution=justset,
-    chainposition=justset,
-    substitution=justset,
-    alternate=justset,
-    multiple=justset,
-    kern=justset,
-    pair=justset,
-    ligature=function(coverage,unicode,ligature)
-      local first=ligature[1]
-      local tree=coverage[first]
-      if not tree then
-        tree={}
-        coverage[first]=tree
-      end
-      for i=2,#ligature do
-        local l=ligature[i]
-        local t=tree[l]
-        if not t then
-          t={}
-          tree[l]=t
-        end
-        tree=t
-      end
-      tree.ligature=unicode
-    end,
-  },
-  register=function(coverage,featuretype,format)
-    return {
-      format=format,
-      coverage=coverage,
-    }
-  end
-}
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-otl”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-oto” 5fbdd899624d4eef639f81b580afe9aa] ---
-
-if not modules then modules={} end modules ['font-oto']={ 
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local concat,unpack=table.concat,table.unpack
-local insert,remove=table.insert,table.remove
-local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip
-local type,next,tonumber,tostring,rawget=type,next,tonumber,tostring,rawget
-local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end)
-local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end)
-local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end)
-local trace_alternatives=false trackers.register("otf.alternatives",function(v) trace_alternatives=v end)
-local trace_ligatures=false trackers.register("otf.ligatures",function(v) trace_ligatures=v end)
-local trace_kerns=false trackers.register("otf.kerns",function(v) trace_kerns=v end)
-local trace_preparing=false trackers.register("otf.preparing",function(v) trace_preparing=v end)
-local report_prepare=logs.reporter("fonts","otf prepare")
-local fonts=fonts
-local otf=fonts.handlers.otf
-local otffeatures=otf.features
-local registerotffeature=otffeatures.register
-otf.defaultbasealternate="none" 
-local wildcard="*"
-local default="dflt"
-local formatters=string.formatters
-local f_unicode=formatters["%U"]
-local f_uniname=formatters["%U (%s)"]
-local f_unilist=formatters["% t (% t)"]
-local function gref(descriptions,n)
-  if type(n)=="number" then
-    local name=descriptions[n].name
-    if name then
-      return f_uniname(n,name)
-    else
-      return f_unicode(n)
-    end
-  elseif n then
-    local num,nam,j={},{},0
-    for i=1,#n do
-      local ni=n[i]
-      if tonumber(ni) then 
-        j=j+1
-        local di=descriptions[ni]
-        num[j]=f_unicode(ni)
-        nam[j]=di and di.name or "-"
-      end
-    end
-    return f_unilist(num,nam)
-  else
-    return "<error in base mode tracing>"
-  end
-end
-local function cref(feature,sequence)
-  return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name)
-end
-local function report_alternate(feature,sequence,descriptions,unicode,replacement,value,comment)
-  report_prepare("%s: base alternate %s => %s (%S => %S)",
-    cref(feature,sequence),
-    gref(descriptions,unicode),
-    replacement and gref(descriptions,replacement),
-    value,
-    comment)
-end
-local function report_substitution(feature,sequence,descriptions,unicode,substitution)
-  report_prepare("%s: base substitution %s => %S",
-    cref(feature,sequence),
-    gref(descriptions,unicode),
-    gref(descriptions,substitution))
-end
-local function report_ligature(feature,sequence,descriptions,unicode,ligature)
-  report_prepare("%s: base ligature %s => %S",
-    cref(feature,sequence),
-    gref(descriptions,ligature),
-    gref(descriptions,unicode))
-end
-local function report_kern(feature,sequence,descriptions,unicode,otherunicode,value)
-  report_prepare("%s: base kern %s + %s => %S",
-    cref(feature,sequence),
-    gref(descriptions,unicode),
-    gref(descriptions,otherunicode),
-    value)
-end
-local basehash,basehashes,applied={},1,{}
-local function registerbasehash(tfmdata)
-  local properties=tfmdata.properties
-  local hash=concat(applied," ")
-  local base=basehash[hash]
-  if not base then
-    basehashes=basehashes+1
-    base=basehashes
-    basehash[hash]=base
-  end
-  properties.basehash=base
-  properties.fullname=(properties.fullname or properties.name).."-"..base
-  applied={}
-end
-local function registerbasefeature(feature,value)
-  applied[#applied+1]=feature.."="..tostring(value)
-end
-local function makefake(tfmdata,name,present)
-  local resources=tfmdata.resources
-  local private=resources.private
-  local character={ intermediate=true,ligatures={} }
-  resources.unicodes[name]=private
-  tfmdata.characters[private]=character
-  tfmdata.descriptions[private]={ name=name }
-  resources.private=private+1
-  present[name]=private
-  return character
-end
-local function make_1(present,tree,name)
-  for k,v in next,tree do
-    if k=="ligature" then
-      present[name]=v
-    else
-      make_1(present,v,name.."_"..k)
-    end
-  end
-end
-local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done)
-  for k,v in next,tree do
-    if k=="ligature" then
-      local character=characters[preceding]
-      if not character then
-        if trace_baseinit then
-          report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding)
-        end
-        character=makefake(tfmdata,name,present)
-      end
-      local ligatures=character.ligatures
-      if ligatures then
-        ligatures[unicode]={ char=v }
-      else
-        character.ligatures={ [unicode]={ char=v } }
-      end
-      if done then
-        local d=done[name]
-        if not d then
-          done[name]={ "dummy",v }
-        else
-          d[#d+1]=v
-        end
-      end
-    else
-      local code=present[name] or unicode
-      local name=name.."_"..k
-      make_2(present,tfmdata,characters,v,name,code,k,done)
-    end
-  end
-end
-local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist)
-  local characters=tfmdata.characters
-  local descriptions=tfmdata.descriptions
-  local resources=tfmdata.resources
-  local changed=tfmdata.changed
-  local ligatures={}
-  local alternate=tonumber(value) or true and 1
-  local defaultalt=otf.defaultbasealternate
-  local trace_singles=trace_baseinit and trace_singles
-  local trace_alternatives=trace_baseinit and trace_alternatives
-  local trace_ligatures=trace_baseinit and trace_ligatures
-  if not changed then
-    changed={}
-    tfmdata.changed=changed
-  end
-  for i=1,#lookuplist do
-    local sequence=lookuplist[i]
-    local steps=sequence.steps
-    local kind=sequence.type
-    if kind=="gsub_single" then
-      for i=1,#steps do
-        for unicode,data in next,steps[i].coverage do
-            if trace_singles then
-              report_substitution(feature,sequence,descriptions,unicode,data)
-            end
-            changed[unicode]=data
-        end
-      end
-    elseif kind=="gsub_alternate" then
-      for i=1,#steps do
-        for unicode,data in next,steps[i].coverage do
-          if not changed[unicode] then
-            local replacement=data[alternate]
-            if replacement then
-              changed[unicode]=replacement
-              if trace_alternatives then
-                report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal")
-              end
-            elseif defaultalt=="first" then
-              replacement=data[1]
-              changed[unicode]=replacement
-              if trace_alternatives then
-                report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
-              end
-            elseif defaultalt=="last" then
-              replacement=data[#data]
-              if trace_alternatives then
-                report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
-              end
-            else
-              if trace_alternatives then
-                report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown")
-              end
-            end
-          end
-        end
-      end
-    elseif kind=="gsub_ligature" then
-      for i=1,#steps do
-        for unicode,data in next,steps[i].coverage do
-          ligatures[#ligatures+1]={ unicode,data,"" } 
-          if trace_ligatures then
-            report_ligature(feature,sequence,descriptions,unicode,data)
-          end
-        end
-      end
-    end
-  end
-  local nofligatures=#ligatures
-  if nofligatures>0 then
-    local characters=tfmdata.characters
-    local present={}
-    local done=trace_baseinit and trace_ligatures and {}
-    for i=1,nofligatures do
-      local ligature=ligatures[i]
-      local unicode,tree=ligature[1],ligature[2]
-      make_1(present,tree,"ctx_"..unicode)
-    end
-    for i=1,nofligatures do
-      local ligature=ligatures[i]
-      local unicode,tree,lookupname=ligature[1],ligature[2],ligature[3]
-      make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence)
-    end
-  end
-end
-local function preparepositionings(tfmdata,feature,value,validlookups,lookuplist)
-  local characters=tfmdata.characters
-  local descriptions=tfmdata.descriptions
-  local resources=tfmdata.resources
-  local properties=tfmdata.properties
-  local traceindeed=trace_baseinit and trace_kerns
-  for i=1,#lookuplist do
-    local sequence=lookuplist[i]
-    local steps=sequence.steps
-    local kind=sequence.type
-    local format=sequence.format
-    if kind=="gpos_pair" then
-      for i=1,#steps do
-        local step=steps[i]
-        if step.format=="kern" then
-          for unicode,data in next,steps[i].coverage do
-            local character=characters[unicode]
-            local kerns=character.kerns
-            if not kerns then
-              kerns={}
-              character.kerns=kerns
-            end
-            if traceindeed then
-              for otherunicode,kern in next,data do
-                if not kerns[otherunicode] and kern~=0 then
-                  kerns[otherunicode]=kern
-                  report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
-                end
-              end
-            else
-              for otherunicode,kern in next,data do
-                if not kerns[otherunicode] and kern~=0 then
-                  kerns[otherunicode]=kern
-                end
-              end
-            end
-          end
-        else
-          for unicode,data in next,steps[i].coverage do
-            local character=characters[unicode]
-            local kerns=character.kerns
-            for otherunicode,kern in next,data do
-              if not kern[2] and not (kerns and kerns[otherunicode]) then
-                local kern=kern[1]
-                if kern[1]~=0 or kern[2]~=0 or kern[4]~=0 then
-                else
-                  kern=kern[3]
-                  if kern~=0 then
-                    if kerns then
-                      kerns[otherunicode]=kern
-                    else
-                      kerns={ [otherunicode]=kern }
-                      character.kerns=kerns
-                    end
-                    if traceindeed then
-                      report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
-                    end
-                  end
-                end
-              end
-            end
-          end
-        end
-      end
-    end
-  end
-end
-local function initializehashes(tfmdata)
-end
-local function featuresinitializer(tfmdata,value)
-  if true then 
-    local starttime=trace_preparing and os.clock()
-    local features=tfmdata.shared.features
-    local fullname=tfmdata.properties.fullname or "?"
-    if features then
-      initializehashes(tfmdata)
-      local collectlookups=otf.collectlookups
-      local rawdata=tfmdata.shared.rawdata
-      local properties=tfmdata.properties
-      local script=properties.script
-      local language=properties.language
-      local rawresources=rawdata.resources
-      local rawfeatures=rawresources and rawresources.features
-      local basesubstitutions=rawfeatures and rawfeatures.gsub
-      local basepositionings=rawfeatures and rawfeatures.gpos
-      if basesubstitutions or basepositionings then
-        local sequences=tfmdata.resources.sequences
-        for s=1,#sequences do
-          local sequence=sequences[s]
-          local sfeatures=sequence.features
-          if sfeatures then
-            local order=sequence.order
-            if order then
-              for i=1,#order do 
-                local feature=order[i]
-                local value=features[feature]
-                if value then
-                  local validlookups,lookuplist=collectlookups(rawdata,feature,script,language)
-                  if not validlookups then
-                  elseif basesubstitutions and basesubstitutions[feature] then
-                    if trace_preparing then
-                      report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value)
-                    end
-                    preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist)
-                    registerbasefeature(feature,value)
-                  elseif basepositionings and basepositionings[feature] then
-                    if trace_preparing then
-                      report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value)
-                    end
-                    preparepositionings(tfmdata,feature,value,validlookups,lookuplist)
-                    registerbasefeature(feature,value)
-                  end
-                end
-              end
-            end
-          end
-        end
-      end
-      registerbasehash(tfmdata)
-    end
-    if trace_preparing then
-      report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname)
-    end
-  end
-end
-registerotffeature {
-  name="features",
-  description="features",
-  default=true,
-  initializers={
-    base=featuresinitializer,
-  }
-}
-otf.basemodeinitializer=featuresinitializer
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-oto”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-otj” 5ea70db9f1990dc1459425853c79f663] ---
-
-if not modules then modules={} end modules ['font-otj']={
-  version=1.001,
-  comment="companion to font-lib.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files",
-}
-if not nodes.properties then return end
-local next,rawget=next,rawget
-local fastcopy=table.fastcopy
-local registertracker=trackers.register
-local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end)
-local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end)
-local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end)
-local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end)
-local use_advance=false directives.register("fonts.injections.advance",function(v) use_advance=v end)
-local report_injections=logs.reporter("fonts","injections")
-local report_spaces=logs.reporter("fonts","spaces")
-local attributes,nodes,node=attributes,nodes,node
-fonts=fonts
-local hashes=fonts.hashes
-local fontdata=hashes.identifiers
-nodes.injections=nodes.injections or {}
-local injections=nodes.injections
-local tracers=nodes.tracers
-local setcolor=tracers and tracers.colors.set
-local resetcolor=tracers and tracers.colors.reset
-local nodecodes=nodes.nodecodes
-local glyph_code=nodecodes.glyph
-local disc_code=nodecodes.disc
-local kern_code=nodecodes.kern
-local glue_code=nodecodes.glue
-local nuts=nodes.nuts
-local nodepool=nuts.pool
-local newkern=nodepool.kern
-local tonode=nuts.tonode
-local tonut=nuts.tonut
-local getfield=nuts.getfield
-local setfield=nuts.setfield
-local getnext=nuts.getnext
-local getprev=nuts.getprev
-local getid=nuts.getid
-local getfont=nuts.getfont
-local getsubtype=nuts.getsubtype
-local getchar=nuts.getchar
-local getboth=nuts.getboth
-local ischar=nuts.is_char
-local getdisc=nuts.getdisc
-local setdisc=nuts.setdisc
-local traverse_id=nuts.traverse_id
-local traverse_char=nuts.traverse_char
-local insert_node_before=nuts.insert_before
-local insert_node_after=nuts.insert_after
-local properties=nodes.properties.data
-function injections.installnewkern(nk)
-  newkern=nk or newkern
-end
-local nofregisteredkerns=0
-local nofregisteredpairs=0
-local nofregisteredmarks=0
-local nofregisteredcursives=0
-local keepregisteredcounts=false
-function injections.keepcounts()
-  keepregisteredcounts=true
-end
-function injections.resetcounts()
-  nofregisteredkerns=0
-  nofregisteredpairs=0
-  nofregisteredmarks=0
-  nofregisteredcursives=0
-  keepregisteredcounts=false
-end
-function injections.reset(n)
-  local p=rawget(properties,n)
-  if p then
-    p.injections=false 
-  else
-    properties[n]=false 
-  end
-end
-function injections.copy(target,source)
-  local sp=rawget(properties,source)
-  if sp then
-    local tp=rawget(properties,target)
-    local si=sp.injections
-    if si then
-      si=fastcopy(si)
-      if tp then
-        tp.injections=si
-      else
-        propertydata[target]={
-          injections=si,
-        }
-      end
-    elseif tp then
-      tp.injections=false 
-    else
-      properties[target]={ injections={} }
-    end
-  else
-    local tp=rawget(properties,target)
-    if tp then
-      tp.injections=false 
-    else
-      properties[target]=false 
-    end
-  end
-end
-function injections.setligaindex(n,index)
-  local p=rawget(properties,n)
-  if p then
-    local i=p.injections
-    if i then
-      i.ligaindex=index
-    else
-      p.injections={
-        ligaindex=index
-      }
-    end
-  else
-    properties[n]={
-      injections={
-        ligaindex=index
-      }
-    }
-  end
-end
-function injections.getligaindex(n,default)
-  local p=rawget(properties,n)
-  if p then
-    local i=p.injections
-    if i then
-      return i.ligaindex or default
-    end
-  end
-  return default
-end
-function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext) 
-  local dx=factor*(exit[1]-entry[1])
-  local dy=-factor*(exit[2]-entry[2])
-  local ws=tfmstart.width
-  local wn=tfmnext.width
-  nofregisteredcursives=nofregisteredcursives+1
-  if rlmode<0 then
-    dx=-(dx+wn)
-  else
-    dx=dx-ws
-  end
-  if dx==0 then
-    dx=0
-  end
-  local p=rawget(properties,start)
-  if p then
-    local i=p.injections
-    if i then
-      i.cursiveanchor=true
-    else
-      p.injections={
-        cursiveanchor=true,
-      }
-    end
-  else
-    properties[start]={
-      injections={
-        cursiveanchor=true,
-      },
-    }
-  end
-  local p=rawget(properties,nxt)
-  if p then
-    local i=p.injections
-    if i then
-      i.cursivex=dx
-      i.cursivey=dy
-    else
-      p.injections={
-        cursivex=dx,
-        cursivey=dy,
-      }
-    end
-  else
-    properties[nxt]={
-      injections={
-        cursivex=dx,
-        cursivey=dy,
-      },
-    }
-  end
-  return dx,dy,nofregisteredcursives
-end
-function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) 
-  local x=factor*spec[1]
-  local y=factor*spec[2]
-  local w=factor*spec[3]
-  local h=factor*spec[4]
-  if x~=0 or w~=0 or y~=0 or h~=0 then 
-    local yoffset=y-h
-    local leftkern=x   
-    local rightkern=w-x 
-    if leftkern~=0 or rightkern~=0 or yoffset~=0 then
-      nofregisteredpairs=nofregisteredpairs+1
-      if rlmode and rlmode<0 then
-        leftkern,rightkern=rightkern,leftkern
-      end
-      if not injection then
-        injection="injections"
-      end
-      local p=rawget(properties,current)
-      if p then
-        local i=rawget(p,injection)
-        if i then
-          if leftkern~=0 then
-            i.leftkern=(i.leftkern or 0)+leftkern
-          end
-          if rightkern~=0 then
-            i.rightkern=(i.rightkern or 0)+rightkern
-          end
-          if yoffset~=0 then
-            i.yoffset=(i.yoffset or 0)+yoffset
-          end
-        elseif leftkern~=0 or rightkern~=0 then
-          p[injection]={
-            leftkern=leftkern,
-            rightkern=rightkern,
-            yoffset=yoffset,
-          }
-        else
-          p[injection]={
-            yoffset=yoffset,
-          }
-        end
-      elseif leftkern~=0 or rightkern~=0 then
-        properties[current]={
-          [injection]={
-            leftkern=leftkern,
-            rightkern=rightkern,
-            yoffset=yoffset,
-          },
-        }
-      else
-        properties[current]={
-          [injection]={
-            yoffset=yoffset,
-          },
-        }
-      end
-      return x,y,w,h,nofregisteredpairs
-     end
-  end
-  return x,y,w,h 
-end
-function injections.setkern(current,factor,rlmode,x,injection)
-  local dx=factor*x
-  if dx~=0 then
-    nofregisteredkerns=nofregisteredkerns+1
-    local p=rawget(properties,current)
-    if not injection then
-      injection="injections"
-    end
-    if p then
-      local i=rawget(p,injection)
-      if i then
-        i.leftkern=dx+(i.leftkern or 0)
-      else
-        p[injection]={
-          leftkern=dx,
-        }
-      end
-    else
-      properties[current]={
-        [injection]={
-          leftkern=dx,
-        },
-      }
-    end
-    return dx,nofregisteredkerns
-  else
-    return 0,0
-  end
-end
-function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) 
-  local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2])
-  nofregisteredmarks=nofregisteredmarks+1
-  if rlmode>=0 then
-    dx=tfmbase.width-dx 
-  end
-  local p=rawget(properties,start)
-  if p then
-    local i=p.injections
-    if i then
-      if i.markmark then
-      else
-        i.markx=dx
-        i.marky=dy
-        i.markdir=rlmode or 0
-        i.markbase=nofregisteredmarks
-        i.markbasenode=base
-        i.markmark=mkmk
-        i.checkmark=checkmark
-      end
-    else
-      p.injections={
-        markx=dx,
-        marky=dy,
-        markdir=rlmode or 0,
-        markbase=nofregisteredmarks,
-        markbasenode=base,
-        markmark=mkmk,
-        checkmark=checkmark,
-      }
-    end
-  else
-    properties[start]={
-      injections={
-        markx=dx,
-        marky=dy,
-        markdir=rlmode or 0,
-        markbase=nofregisteredmarks,
-        markbasenode=base,
-        markmark=mkmk,
-        checkmark=checkmark,
-      },
-    }
-  end
-  return dx,dy,nofregisteredmarks
-end
-local function dir(n)
-  return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset"
-end
-local function showchar(n,nested)
-  local char=getchar(n)
-  report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char)
-end
-local function show(n,what,nested,symbol)
-  if n then
-    local p=rawget(properties,n)
-    if p then
-      local i=rawget(p,what)
-      if i then
-        local leftkern=i.leftkern or 0
-        local rightkern=i.rightkern or 0
-        local yoffset=i.yoffset  or 0
-        local markx=i.markx   or 0
-        local marky=i.marky   or 0
-        local markdir=i.markdir  or 0
-        local markbase=i.markbase or 0
-        local cursivex=i.cursivex or 0
-        local cursivey=i.cursivey or 0
-        local ligaindex=i.ligaindex or 0
-        local cursbase=i.cursiveanchor
-        local margin=nested and 4 or 2
-        if rightkern~=0 or yoffset~=0 then
-          report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset)
-        elseif leftkern~=0 then
-          report_injections("%w%s kern: dx %p",margin,symbol,leftkern)
-        end
-        if markx~=0 or marky~=0 or markbase~=0 then
-          report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no")
-        end
-        if cursivex~=0 or cursivey~=0 then
-          if cursbase then
-            report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey)
-          else
-            report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey)
-          end
-        elseif cursbase then
-          report_injections("%w%s curs: base",margin,symbol)
-        end
-        if ligaindex~=0 then
-          report_injections("%w%s liga: index %i",margin,symbol,ligaindex)
-        end
-      end
-    end
-  end
-end
-local function showsub(n,what,where)
-  report_injections("begin subrun: %s",where)
-  for n in traverse_id(glyph_code,n) do
-    showchar(n,where)
-    show(n,what,where," ")
-  end
-  report_injections("end subrun")
-end
-local function trace(head,where)
-  report_injections("begin run %s: %s kerns, %s pairs, %s marks and %s cursives registered",
-    where or "",nofregisteredkerns,nofregisteredpairs,nofregisteredmarks,nofregisteredcursives)
-  local n=head
-  while n do
-    local id=getid(n)
-    if id==glyph_code then
-      showchar(n)
-      show(n,"injections",false," ")
-      show(n,"preinjections",false,"<")
-      show(n,"postinjections",false,">")
-      show(n,"replaceinjections",false,"=")
-      show(n,"emptyinjections",false,"*")
-    elseif id==disc_code then
-      local pre,post,replace=getdisc(n)
-      if pre then
-        showsub(pre,"preinjections","pre")
-      end
-      if post then
-        showsub(post,"postinjections","post")
-      end
-      if replace then
-        showsub(replace,"replaceinjections","replace")
-      end
-      show(n,"emptyinjections",false,"*")
-    end
-    n=getnext(n)
-  end
-  report_injections("end run")
-end
-local function show_result(head)
-  local current=head
-  local skipping=false
-  while current do
-    local id=getid(current)
-    if id==glyph_code then
-      report_injections("char: %C, width %p, xoffset %p, yoffset %p",
-        getchar(current),getfield(current,"width"),getfield(current,"xoffset"),getfield(current,"yoffset"))
-      skipping=false
-    elseif id==kern_code then
-      report_injections("kern: %p",getfield(current,"kern"))
-      skipping=false
-    elseif not skipping then
-      report_injections()
-      skipping=true
-    end
-    current=getnext(current)
-  end
-end
-local function inject_kerns_only(head,where)
-  head=tonut(head)
-  if trace_injections then
-    trace(head,"kerns")
-  end
-  local current=head
-  local prev=nil
-  local next=nil
-  local prevdisc=nil
-  local prevglyph=nil
-  local pre=nil 
-  local post=nil 
-  local replace=nil 
-  local pretail=nil 
-  local posttail=nil 
-  local replacetail=nil 
-  while current do
-    local id=getid(current)
-    local next=getnext(current)
-    if id==glyph_code then
-      if getsubtype(current)<256 then
-        local p=rawget(properties,current)
-        if p then
-          local i=p.injections
-          if i then
-            local leftkern=i.leftkern
-            if leftkern and leftkern~=0 then
-              if use_advance then
-                setfield(current,"xoffset",leftkern)
-                setfield(current,"xadvance",leftkern)
-              else
-                insert_node_before(head,current,newkern(leftkern))
-              end
-            end
-          end
-          if prevdisc then
-            local done=false
-            if post then
-              local i=p.postinjections
-              if i then
-                local leftkern=i.leftkern
-                if leftkern and leftkern~=0 then
-                  if use_advance then
-                    setfield(post,"xadvance",leftkern)
-                  else
-                    insert_node_after(post,posttail,newkern(leftkern))
-                    done=true
-                  end
-                end
-              end
-            end
-            if replace then
-              local i=p.replaceinjections
-              if i then
-                local leftkern=i.leftkern
-                if leftkern and leftkern~=0 then
-                  if use_advance then
-                    setfield(replace,"xadvance",leftkern)
-                  else
-                    insert_node_after(replace,replacetail,newkern(leftkern))
-                    done=true
-                  end
-                end
-              end
-            else
-              local i=p.emptyinjections
-              if i then
-                local leftkern=i.leftkern
-                if leftkern and leftkern~=0 then
-                  setfield(prev,"replace",newkern(leftkern)) 
-                end
-              end
-            end
-            if done then
-              setdisc(prevdisc,pre,post,replace)
-            end
-          end
-        end
-      end
-      prevdisc=nil
-      prevglyph=current
-    elseif id==disc_code then
-      pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
-      local done=false
-      if pre then
-        for n in traverse_char(pre) do
-          local p=rawget(properties,n)
-          if p then
-            local i=p.injections or p.preinjections
-            if i then
-              local leftkern=i.leftkern
-              if leftkern and leftkern~=0 then
-                if use_advance then
-                  setfield(pre,"xoffset",leftkern)
-                  setfield(pre,"xadvance",leftkern)
-                else
-                  pre=insert_node_before(pre,n,newkern(leftkern))
-                  done=true
-                end
-              end
-            end
-          end
-        end
-      end
-      if post then
-        for n in traverse_char(post) do
-          local p=rawget(properties,n)
-          if p then
-            local i=p.injections or p.postinjections
-            if i then
-              local leftkern=i.leftkern
-              if leftkern and leftkern~=0 then
-                if use_advance then
-                  setfield(post,"xoffset",leftkern)
-                  setfield(post,"xadvance",leftkern)
-                else
-                  post=insert_node_before(post,n,newkern(leftkern))
-                  done=true
-                end
-              end
-            end
-          end
-        end
-      end
-      if replace then
-        for n in traverse_char(replace) do
-          local p=rawget(properties,n)
-          if p then
-            local i=p.injections or p.replaceinjections
-            if i then
-              local leftkern=i.leftkern
-              if leftkern and leftkern~=0 then
-                if use_advance then
-                  setfield(replace,"xoffset",leftkern)
-                  setfield(replace,"xadvance",leftkern)
-                else
-                  replace=insert_node_before(replace,n,newkern(leftkern))
-                  done=true
-                end
-              end
-            end
-          end
-        end
-      end
-      if done then
-        setdisc(current,pre,post,replace)
-      end
-      prevglyph=nil
-      prevdisc=current
-    else
-      prevglyph=nil
-      prevdisc=nil
-    end
-    prev=current
-    current=next
-  end
-  if keepregisteredcounts then
-    keepregisteredcounts=false
-  else
-    nofregisteredkerns=0
-  end
-  return tonode(head),true
-end
-local function inject_pairs_only(head,where)
-  head=tonut(head)
-  if trace_injections then
-    trace(head,"pairs")
-  end
-  local current=head
-  local prev=nil
-  local next=nil
-  local prevdisc=nil
-  local prevglyph=nil
-  local pre=nil 
-  local post=nil 
-  local replace=nil 
-  local pretail=nil 
-  local posttail=nil 
-  local replacetail=nil 
-  while current do
-    local id=getid(current)
-    local next=getnext(current)
-    if id==glyph_code then
-      if getsubtype(current)<256 then
-        local p=rawget(properties,current)
-        if p then
-          local i=p.injections
-          if i then
-            local yoffset=i.yoffset
-            if yoffset and yoffset~=0 then
-              setfield(current,"yoffset",yoffset)
-            end
-            local leftkern=i.leftkern
-            if leftkern and leftkern~=0 then
-              head=insert_node_before(head,current,newkern(leftkern))
-            end
-            local rightkern=i.rightkern
-            if rightkern and rightkern~=0 then
-              insert_node_after(head,current,newkern(rightkern))
-            end
-          else
-            local i=p.emptyinjections
-            if i then
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                if next and getid(next)==disc_code then
-                  if replace then
-                  else
-                    setfield(next,"replace",newkern(rightkern)) 
-                  end
-                end
-              end
-            end
-          end
-          if prevdisc then
-            local done=false
-            if post then
-              local i=p.postinjections
-              if i then
-                local leftkern=i.leftkern
-                if leftkern and leftkern~=0 then
-                  insert_node_after(post,posttail,newkern(leftkern))
-                  done=true
-                end
-              end
-            end
-            if replace then
-              local i=p.replaceinjections
-              if i then
-                local leftkern=i.leftkern
-                if leftkern and leftkern~=0 then
-                  insert_node_after(replace,replacetail,newkern(leftkern))
-                  done=true
-                end
-              end
-            else
-              local i=p.emptyinjections
-              if i then
-                local leftkern=i.leftkern
-                if leftkern and leftkern~=0 then
-                  setfield(prev,"replace",newkern(leftkern)) 
-                end
-              end
-            end
-            if done then
-              setdisc(prevdisc,pre,post,replace)
-            end
-          end
-        end
-      end
-      prevdisc=nil
-      prevglyph=current
-    elseif id==disc_code then
-      pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
-      local done=false
-      if pre then
-        for n in traverse_char(pre) do
-          local p=rawget(properties,n)
-          if p then
-            local i=p.injections or p.preinjections
-            if i then
-              local yoffset=i.yoffset
-              if yoffset and yoffset~=0 then
-                setfield(n,"yoffset",yoffset)
-              end
-              local leftkern=i.leftkern
-              if leftkern and leftkern~=0 then
-                pre=insert_node_before(pre,n,newkern(leftkern))
-                done=true
-              end
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                insert_node_after(pre,n,newkern(rightkern))
-                done=true
-              end
-            end
-          end
-        end
-      end
-      if post then
-        for n in traverse_char(post) do
-          local p=rawget(properties,n)
-          if p then
-            local i=p.injections or p.postinjections
-            if i then
-              local yoffset=i.yoffset
-              if yoffset and yoffset~=0 then
-                setfield(n,"yoffset",yoffset)
-              end
-              local leftkern=i.leftkern
-              if leftkern and leftkern~=0 then
-                post=insert_node_before(post,n,newkern(leftkern))
-                done=true
-              end
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                insert_node_after(post,n,newkern(rightkern))
-                done=true
-              end
-            end
-          end
-        end
-      end
-      if replace then
-        for n in traverse_char(replace) do
-          local p=rawget(properties,n)
-          if p then
-            local i=p.injections or p.replaceinjections
-            if i then
-              local yoffset=i.yoffset
-              if yoffset and yoffset~=0 then
-                setfield(n,"yoffset",yoffset)
-              end
-              local leftkern=i.leftkern
-              if leftkern and leftkern~=0 then
-                replace=insert_node_before(replace,n,newkern(leftkern))
-                done=true
-              end
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                insert_node_after(replace,n,newkern(rightkern))
-                done=true
-              end
-            end
-          end
-        end
-      end
-      if prevglyph then
-        if pre then
-          local p=rawget(properties,prevglyph)
-          if p then
-            local i=p.preinjections
-            if i then
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                pre=insert_node_before(pre,pre,newkern(rightkern))
-                done=true
-              end
-            end
-          end
-        end
-        if replace then
-          local p=rawget(properties,prevglyph)
-          if p then
-            local i=p.replaceinjections
-            if i then
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                replace=insert_node_before(replace,replace,newkern(rightkern))
-                done=true
-              end
-            end
-          end
-        end
-      end
-      if done then
-        setdisc(current,pre,post,replace)
-      end
-      prevglyph=nil
-      prevdisc=current
-    else
-      prevglyph=nil
-      prevdisc=nil
-    end
-    prev=current
-    current=next
-  end
-  if keepregisteredcounts then
-    keepregisteredcounts=false
-  else
-    nofregisteredkerns=0
-  end
-  return tonode(head),true
-end
-local function showoffset(n,flag)
-  local o=getfield(n,"xoffset")
-  if o==0 then
-    o=getfield(n,"yoffset")
-  end
-  if o~=0 then
-    setcolor(n,flag and "darkred" or "darkgreen")
-  else
-    resetcolor(n)
-  end
-end
-local function inject_everything(head,where)
-  head=tonut(head)
-  if trace_injections then
-    trace(head,"everything")
-  end
-  local hascursives=nofregisteredcursives>0
-  local hasmarks=nofregisteredmarks>0
-  local current=head
-  local last=nil
-  local font=font
-  local markdata=nil
-  local prev=nil
-  local next=nil
-  local prevdisc=nil
-  local prevglyph=nil
-  local pre=nil 
-  local post=nil 
-  local replace=nil 
-  local pretail=nil 
-  local posttail=nil 
-  local replacetail=nil
-  local cursiveanchor=nil
-  local minc=0
-  local maxc=0
-  local glyphs={}
-  local marks={}
-  local nofmarks=0
-  local function processmark(p,n,pn) 
-    local px=getfield(p,"xoffset")
-    local ox=0
-    local rightkern=nil
-    local pp=rawget(properties,p)
-    if pp then
-      pp=pp.injections
-      if pp then
-        rightkern=pp.rightkern
-      end
-    end
-    if rightkern then 
-      if pn.markdir<0 then
-        ox=px-pn.markx-rightkern
-      else
-        if false then
-          local leftkern=pp.leftkern
-          if leftkern then
-            ox=px-pn.markx-leftkern
-          else
-            ox=px-pn.markx
-          end
-        else
-          ox=px-pn.markx
-        end
-      end
-    else
-        ox=px-pn.markx
-      if pn.checkmark then
-        local wn=getfield(n,"width") 
-        if wn~=0 then
-          wn=wn/2
-          if trace_injections then
-            report_injections("correcting non zero width mark %C",getchar(n))
-          end
-          insert_node_before(n,n,newkern(-wn))
-          insert_node_after(n,n,newkern(-wn))
-        end
-      end
-    end
-    local oy=getfield(n,"yoffset")+getfield(p,"yoffset")+pn.marky
-    setfield(n,"xoffset",ox)
-    setfield(n,"yoffset",oy)
-    if trace_marks then
-      showoffset(n,true)
-    end
-  end
-  while current do
-    local id=getid(current)
-    local next=getnext(current)
-    if id==glyph_code then
-      if getsubtype(current)<256 then
-        local p=rawget(properties,current)
-        if p then
-          local i=p.injections
-          if i then
-            local pm=i.markbasenode
-            if pm then
-              nofmarks=nofmarks+1
-              marks[nofmarks]=current
-            else
-              local yoffset=i.yoffset
-              if yoffset and yoffset~=0 then
-                setfield(current,"yoffset",yoffset)
-              end
-              if hascursives then
-                local cursivex=i.cursivex
-                if cursivex then
-                  if cursiveanchor then
-                    if cursivex~=0 then
-                      i.leftkern=(i.leftkern or 0)+cursivex
-                    end
-                    if maxc==0 then
-                      minc=1
-                      maxc=1
-                      glyphs[1]=cursiveanchor
-                    else
-                      maxc=maxc+1
-                      glyphs[maxc]=cursiveanchor
-                    end
-                    properties[cursiveanchor].cursivedy=i.cursivey 
-                    last=current
-                  else
-                    maxc=0
-                  end
-                elseif maxc>0 then
-                  local ny=getfield(current,"yoffset")
-                  for i=maxc,minc,-1 do
-                    local ti=glyphs[i]
-                    ny=ny+properties[ti].cursivedy
-                    setfield(ti,"yoffset",ny) 
-                    if trace_cursive then
-                      showoffset(ti)
-                    end
-                  end
-                  maxc=0
-                  cursiveanchor=nil
-                end
-                if i.cursiveanchor then
-                  cursiveanchor=current 
-                else
-                  if maxc>0 then
-                    local ny=getfield(current,"yoffset")
-                    for i=maxc,minc,-1 do
-                      local ti=glyphs[i]
-                      ny=ny+properties[ti].cursivedy
-                      setfield(ti,"yoffset",ny) 
-                      if trace_cursive then
-                        showoffset(ti)
-                      end
-                    end
-                    maxc=0
-                  end
-                  cursiveanchor=nil
-                end
-              end
-              local leftkern=i.leftkern
-              if leftkern and leftkern~=0 then
-                insert_node_before(head,current,newkern(leftkern))
-              end
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                insert_node_after(head,current,newkern(rightkern))
-              end
-            end
-          else
-            local i=p.emptyinjections
-            if i then
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                if next and getid(next)==disc_code then
-                  if replace then
-                  else
-                    setfield(next,"replace",newkern(rightkern)) 
-                  end
-                end
-              end
-            end
-          end
-          if prevdisc then
-            if p then
-              local done=false
-              if post then
-                local i=p.postinjections
-                if i then
-                  local leftkern=i.leftkern
-                  if leftkern and leftkern~=0 then
-                    insert_node_after(post,posttail,newkern(leftkern))
-                    done=true
-                  end
-                end
-              end
-              if replace then
-                local i=p.replaceinjections
-                if i then
-                  local leftkern=i.leftkern
-                  if leftkern and leftkern~=0 then
-                    insert_node_after(replace,replacetail,newkern(leftkern))
-                    done=true
-                  end
-                end
-              else
-                local i=p.emptyinjections
-                if i then
-                  local leftkern=i.leftkern
-                  if leftkern and leftkern~=0 then
-                    setfield(prev,"replace",newkern(leftkern)) 
-                  end
-                end
-              end
-              if done then
-                setdisc(prevdisc,pre,post,replace)
-              end
-            end
-          end
-        else
-          if hascursives and maxc>0 then
-            local ny=getfield(current,"yoffset")
-            for i=maxc,minc,-1 do
-              local ti=glyphs[i]
-              ny=ny+properties[ti].cursivedy
-              setfield(ti,"yoffset",getfield(ti,"yoffset")+ny) 
-            end
-            maxc=0
-            cursiveanchor=nil
-          end
-        end
-      end
-      prevdisc=nil
-      prevglyph=current
-    elseif id==disc_code then
-      pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
-      local done=false
-      if pre then
-        for n in traverse_char(pre) do
-          local p=rawget(properties,n)
-          if p then
-            local i=p.injections or p.preinjections
-            if i then
-              local yoffset=i.yoffset
-              if yoffset and yoffset~=0 then
-                setfield(n,"yoffset",yoffset)
-              end
-              local leftkern=i.leftkern
-              if leftkern and leftkern~=0 then
-                pre=insert_node_before(pre,n,newkern(leftkern))
-                done=true
-              end
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                insert_node_after(pre,n,newkern(rightkern))
-                done=true
-              end
-              if hasmarks then
-                local pm=i.markbasenode
-                if pm then
-                  processmark(pm,current,i)
-                end
-              end
-            end
-          end
-        end
-      end
-      if post then
-        for n in traverse_char(post) do
-          local p=rawget(properties,n)
-          if p then
-            local i=p.injections or p.postinjections
-            if i then
-              local yoffset=i.yoffset
-              if yoffset and yoffset~=0 then
-                setfield(n,"yoffset",yoffset)
-              end
-              local leftkern=i.leftkern
-              if leftkern and leftkern~=0 then
-                post=insert_node_before(post,n,newkern(leftkern))
-                done=true
-              end
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                insert_node_after(post,n,newkern(rightkern))
-                done=true
-              end
-              if hasmarks then
-                local pm=i.markbasenode
-                if pm then
-                  processmark(pm,current,i)
-                end
-              end
-            end
-          end
-        end
-      end
-      if replace then
-        for n in traverse_char(replace) do
-          local p=rawget(properties,n)
-          if p then
-            local i=p.injections or p.replaceinjections
-            if i then
-              local yoffset=i.yoffset
-              if yoffset and yoffset~=0 then
-                setfield(n,"yoffset",yoffset)
-              end
-              local leftkern=i.leftkern
-              if leftkern and leftkern~=0 then
-                replace=insert_node_before(replace,n,newkern(leftkern))
-                done=true
-              end
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                insert_node_after(replace,n,newkern(rightkern))
-                done=true
-              end
-              if hasmarks then
-                local pm=i.markbasenode
-                if pm then
-                  processmark(pm,current,i)
-                end
-              end
-            end
-          end
-        end
-      end
-      if prevglyph then
-        if pre then
-          local p=rawget(properties,prevglyph)
-          if p then
-            local i=p.preinjections
-            if i then
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                pre=insert_node_before(pre,pre,newkern(rightkern))
-                done=true
-              end
-            end
-          end
-        end
-        if replace then
-          local p=rawget(properties,prevglyph)
-          if p then
-            local i=p.replaceinjections
-            if i then
-              local rightkern=i.rightkern
-              if rightkern and rightkern~=0 then
-                replace=insert_node_before(replace,replace,newkern(rightkern))
-                done=true
-              end
-            end
-          end
-        end
-      end
-      if done then
-        setdisc(current,pre,post,replace)
-      end
-      prevglyph=nil
-      prevdisc=current
-    else
-      prevglyph=nil
-      prevdisc=nil
-    end
-    prev=current
-    current=next
-  end
-  if hascursives and maxc>0 then
-    local ny=getfield(last,"yoffset")
-    for i=maxc,minc,-1 do
-      local ti=glyphs[i]
-      ny=ny+properties[ti].cursivedy
-      setfield(ti,"yoffset",ny) 
-      if trace_cursive then
-        showoffset(ti)
-      end
-    end
-  end
-  if nofmarks>0 then
-    for i=1,nofmarks do
-      local m=marks[i]
-      local p=rawget(properties,m)
-      local i=p.injections
-      local b=i.markbasenode
-      processmark(b,m,i)
-    end
-  elseif hasmarks then
-  end
-  if keepregisteredcounts then
-    keepregisteredcounts=false
-  else
-    nofregisteredkerns=0
-    nofregisteredpairs=0
-    nofregisteredmarks=0
-    nofregisteredcursives=0
-  end
-  return tonode(head),true
-end
-local triggers=false
-function nodes.injections.setspacekerns(font,sequence)
-  if triggers then
-    triggers[font]=sequence
-  else
-    triggers={ [font]=sequence }
-  end
-end
-local getthreshold
-if context then
-  local threshold=1 
-  local parameters=fonts.hashes.parameters
-  directives.register("otf.threshold",function(v) threshold=tonumber(v) or 1 end)
-  getthreshold=function(font)
-    local p=parameters[font]
-    local f=p.factor
-    local s=p.spacing
-    local t=threshold*(s and s.width or p.space or 0)-2
-    return t>0 and t or 0,f
-  end
-else
-  injections.threshold=0
-  getthreshold=function(font)
-    local p=fontdata[font].parameters
-    local f=p.factor
-    local s=p.spacing
-    local t=injections.threshold*(s and s.width or p.space or 0)-2
-    return t>0 and t or 0,f
-  end
-end
-injections.getthreshold=getthreshold
-function injections.isspace(n,threshold)
-  if getid(n)==glue_code then
-    local w=getfield(n,"width")
-    if threshold and w>threshold then 
-      return 32
-    end
-  end
-end
-local function injectspaces(head)
-  if not triggers then
-    return head,false
-  end
-  local lastfont=nil
-  local spacekerns=nil
-  local leftkerns=nil
-  local rightkerns=nil
-  local factor=0
-  local threshold=0
-  local leftkern=false
-  local rightkern=false
-  local function updatefont(font,trig)
-    leftkerns=trig.left
-    rightkerns=trig.right
-    lastfont=font
-    threshold,
-    factor=getthreshold(font)
-  end
-  for n in traverse_id(glue_code,tonut(head)) do
-    local prev,next=getboth(n)
-    local prevchar=ischar(prev)
-    local nextchar=ischar(next)
-    if nextchar then
-      local font=getfont(next)
-      local trig=triggers[font]
-      if trig then
-        if lastfont~=font then
-          updatefont(font,trig)
-        end
-        if rightkerns then
-          rightkern=rightkerns[nextchar]
-        end
-      end
-    end
-    if prevchar then
-      local font=getfont(prev)
-      local trig=triggers[font]
-      if trig then
-        if lastfont~=font then
-          updatefont(font,trig)
-        end
-        if leftkerns then
-          leftkern=leftkerns[prevchar]
-        end
-      end
-    end
-    if leftkern then
-      local old=getfield(n,"width")
-      if old>threshold then
-        if rightkern then
-          local new=old+(leftkern+rightkern)*factor
-          if trace_spaces then
-            report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar)
-          end
-          setfield(n,"width",new)
-          leftkern=false
-        else
-          local new=old+leftkern*factor
-          if trace_spaces then
-            report_spaces("%C [%p -> %p]",prevchar,old,new)
-          end
-          setfield(n,"width",new)
-        end
-      end
-      leftkern=false
-    elseif rightkern then
-      local old=getfield(n,"width")
-      if old>threshold then
-        local new=old+rightkern*factor
-        if trace_spaces then
-          report_spaces("[%p -> %p] %C",nextchar,old,new)
-        end
-        setfield(n,"width",new)
-      end
-      rightkern=false
-    end
-  end
-  triggers=false
-  return head,true
-end
-function injections.handler(head,where)
-  if triggers then
-    head=injectspaces(head)
-  end
-  if nofregisteredmarks>0 or nofregisteredcursives>0 then
-    if trace_injections then
-      report_injections("injection variant %a","everything")
-    end
-    return inject_everything(head,where)
-  elseif nofregisteredpairs>0 then
-    if trace_injections then
-      report_injections("injection variant %a","pairs")
-    end
-    return inject_pairs_only(head,where)
-  elseif nofregisteredkerns>0 then
-    if trace_injections then
-      report_injections("injection variant %a","kerns")
-    end
-    return inject_kerns_only(head,where)
-  else
-    return head,false
-  end
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-otj”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-ota” c281d18dfc89a8ca18af64f55e9fa92b] ---
-
-if not modules then modules={} end modules ['font-ota']={
-  version=1.001,
-  comment="companion to font-otf.lua (analysing)",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local type=type
-if not trackers then trackers={ register=function() end } end
-local fonts,nodes,node=fonts,nodes,node
-local allocate=utilities.storage.allocate
-local otf=fonts.handlers.otf
-local analyzers=fonts.analyzers
-local initializers=allocate()
-local methods=allocate()
-analyzers.initializers=initializers
-analyzers.methods=methods
-local a_state=attributes.private('state')
-local nuts=nodes.nuts
-local tonut=nuts.tonut
-local getfield=nuts.getfield
-local getnext=nuts.getnext
-local getprev=nuts.getprev
-local getprev=nuts.getprev
-local getprop=nuts.getprop
-local setprop=nuts.setprop
-local getfont=nuts.getfont
-local getsubtype=nuts.getsubtype
-local getchar=nuts.getchar
-local ischar=nuts.is_char
-local traverse_id=nuts.traverse_id
-local end_of_math=nuts.end_of_math
-local nodecodes=nodes.nodecodes
-local disc_code=nodecodes.disc
-local math_code=nodecodes.math
-local fontdata=fonts.hashes.identifiers
-local categories=characters and characters.categories or {} 
-local chardata=characters and characters.data
-local otffeatures=fonts.constructors.features.otf
-local registerotffeature=otffeatures.register
-local s_init=1  local s_rphf=7
-local s_medi=2  local s_half=8
-local s_fina=3  local s_pref=9
-local s_isol=4  local s_blwf=10
-local s_mark=5  local s_pstf=11
-local s_rest=6
-local states={
-  init=s_init,
-  medi=s_medi,
-  med2=s_medi,
-  fina=s_fina,
-  fin2=s_fina,
-  fin3=s_fina,
-  isol=s_isol,
-  mark=s_mark,
-  rest=s_rest,
-  rphf=s_rphf,
-  half=s_half,
-  pref=s_pref,
-  blwf=s_blwf,
-  pstf=s_pstf,
-}
-local features={
-  init=s_init,
-  medi=s_medi,
-  med2=s_medi,
-  fina=s_fina,
-  fin2=s_fina,
-  fin3=s_fina,
-  isol=s_isol,
-  rphf=s_rphf,
-  half=s_half,
-  pref=s_pref,
-  blwf=s_blwf,
-  pstf=s_pstf,
-}
-analyzers.states=states
-analyzers.features=features
-analyzers.useunicodemarks=false
-function analyzers.setstate(head,font)
-  local useunicodemarks=analyzers.useunicodemarks
-  local tfmdata=fontdata[font]
-  local descriptions=tfmdata.descriptions
-  local first,last,current,n,done=nil,nil,head,0,false 
-  current=tonut(current)
-  while current do
-    local char,id=ischar(current,font)
-    if char and not getprop(current,a_state) then
-      done=true
-      local d=descriptions[char]
-      if d then
-        if d.class=="mark" then
-          done=true
-          setprop(current,a_state,s_mark)
-        elseif useunicodemarks and categories[char]=="mn" then
-          done=true
-          setprop(current,a_state,s_mark)
-        elseif n==0 then
-          first,last,n=current,current,1
-          setprop(current,a_state,s_init)
-        else
-          last,n=current,n+1
-          setprop(current,a_state,s_medi)
-        end
-      else 
-        if first and first==last then
-          setprop(last,a_state,s_isol)
-        elseif last then
-          setprop(last,a_state,s_fina)
-        end
-        first,last,n=nil,nil,0
-      end
-    elseif char==false then
-      if first and first==last then
-        setprop(last,a_state,s_isol)
-      elseif last then
-        setprop(last,a_state,s_fina)
-      end
-      first,last,n=nil,nil,0
-      if id==math_code then
-        current=end_of_math(current)
-      end
-    elseif id==disc_code then
-      setprop(current,a_state,s_medi)
-      last=current
-    else 
-      if first and first==last then
-        setprop(last,a_state,s_isol)
-      elseif last then
-        setprop(last,a_state,s_fina)
-      end
-      first,last,n=nil,nil,0
-      if id==math_code then
-        current=end_of_math(current)
-      end
-    end
-    current=getnext(current)
-  end
-  if first and first==last then
-    setprop(last,a_state,s_isol)
-  elseif last then
-    setprop(last,a_state,s_fina)
-  end
-  return head,done
-end
-local function analyzeinitializer(tfmdata,value) 
-  local script,language=otf.scriptandlanguage(tfmdata) 
-  local action=initializers[script]
-  if not action then
-  elseif type(action)=="function" then
-    return action(tfmdata,value)
-  else
-    local action=action[language]
-    if action then
-      return action(tfmdata,value)
-    end
-  end
-end
-local function analyzeprocessor(head,font,attr)
-  local tfmdata=fontdata[font]
-  local script,language=otf.scriptandlanguage(tfmdata,attr)
-  local action=methods[script]
-  if not action then
-  elseif type(action)=="function" then
-    return action(head,font,attr)
-  else
-    action=action[language]
-    if action then
-      return action(head,font,attr)
-    end
-  end
-  return head,false
-end
-registerotffeature {
-  name="analyze",
-  description="analysis of character classes",
-  default=true,
-  initializers={
-    node=analyzeinitializer,
-  },
-  processors={
-    position=1,
-    node=analyzeprocessor,
-  }
-}
-methods.latn=analyzers.setstate
-local arab_warned={}
-local function warning(current,what)
-  local char=getchar(current)
-  if not arab_warned[char] then
-    log.report("analyze","arab: character %C has no %a class",char,what)
-    arab_warned[char]=true
-  end
-end
-local mappers={
-  l=s_init,
-  d=s_medi,
-  c=s_medi,
-  r=s_fina,
-  u=s_isol,
-}
-local classifiers=characters.classifiers
-if not classifiers then
-  local f_arabic,l_arabic=characters.blockrange("arabic")
-  local f_syriac,l_syriac=characters.blockrange("syriac")
-  local f_mandiac,l_mandiac=characters.blockrange("mandiac")
-  local f_nko,l_nko=characters.blockrange("nko")
-  local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda")
-  classifiers=table.setmetatableindex(function(t,k)
-    if type(k)=="number" then
-      local c=chardata[k]
-      local v=false
-      if c then
-        local arabic=c.arabic
-        if arabic then
-          v=mappers[arabic]
-          if not v then
-            log.report("analyze","error in mapping arabic %C",k)
-            v=false
-          end
-        elseif (k>=f_arabic and k<=l_arabic) or
-            (k>=f_syriac and k<=l_syriac) or
-            (k>=f_mandiac and k<=l_mandiac) or
-            (k>=f_nko   and k<=l_nko)   or
-            (k>=f_ext_a  and k<=l_ext_a)  then
-          if categories[k]=="mn" then
-            v=s_mark
-          else
-            v=s_rest
-          end
-        end
-      end
-      t[k]=v
-      return v
-    end
-  end)
-  characters.classifiers=classifiers
-end
-function methods.arab(head,font,attr)
-  local first,last=nil,nil
-  local c_first,c_last=nil,nil
-  local current,done=head,false
-  current=tonut(current)
-  while current do
-    local char,id=ischar(current,font)
-    if char and not getprop(current,a_state) then
-      done=true
-      local classifier=classifiers[char]
-      if not classifier then
-        if last then
-          if c_last==s_medi or c_last==s_fina then
-            setprop(last,a_state,s_fina)
-          else
-            warning(last,"fina")
-            setprop(last,a_state,s_error)
-          end
-          first,last=nil,nil
-        elseif first then
-          if c_first==s_medi or c_first==s_fina then
-            setprop(first,a_state,s_isol)
-          else
-            warning(first,"isol")
-            setprop(first,a_state,s_error)
-          end
-          first=nil
-        end
-      elseif classifier==s_mark then
-        setprop(current,a_state,s_mark)
-      elseif classifier==s_isol then
-        if last then
-          if c_last==s_medi or c_last==s_fina then
-            setprop(last,a_state,s_fina)
-          else
-            warning(last,"fina")
-            setprop(last,a_state,s_error)
-          end
-          first,last=nil,nil
-        elseif first then
-          if c_first==s_medi or c_first==s_fina then
-            setprop(first,a_state,s_isol)
-          else
-            warning(first,"isol")
-            setprop(first,a_state,s_error)
-          end
-          first=nil
-        end
-        setprop(current,a_state,s_isol)
-      elseif classifier==s_medi then
-        if first then
-          last=current
-          c_last=classifier
-          setprop(current,a_state,s_medi)
-        else
-          setprop(current,a_state,s_init)
-          first=current
-          c_first=classifier
-        end
-      elseif classifier==s_fina then
-        if last then
-          if getprop(last,a_state)~=s_init then
-            setprop(last,a_state,s_medi)
-          end
-          setprop(current,a_state,s_fina)
-          first,last=nil,nil
-        elseif first then
-          setprop(current,a_state,s_fina)
-          first=nil
-        else
-          setprop(current,a_state,s_isol)
-        end
-      else 
-        setprop(current,a_state,s_rest)
-        if last then
-          if c_last==s_medi or c_last==s_fina then
-            setprop(last,a_state,s_fina)
-          else
-            warning(last,"fina")
-            setprop(last,a_state,s_error)
-          end
-          first,last=nil,nil
-        elseif first then
-          if c_first==s_medi or c_first==s_fina then
-            setprop(first,a_state,s_isol)
-          else
-            warning(first,"isol")
-            setprop(first,a_state,s_error)
-          end
-          first=nil
-        end
-      end
-    else
-      if last then
-        if c_last==s_medi or c_last==s_fina then
-          setprop(last,a_state,s_fina)
-        else
-          warning(last,"fina")
-          setprop(last,a_state,s_error)
-        end
-        first,last=nil,nil
-      elseif first then
-        if c_first==s_medi or c_first==s_fina then
-          setprop(first,a_state,s_isol)
-        else
-          warning(first,"isol")
-          setprop(first,a_state,s_error)
-        end
-        first=nil
-      end
-      if id==math_code then 
-        current=end_of_math(current)
-      end
-    end
-    current=getnext(current)
-  end
-  if last then
-    if c_last==s_medi or c_last==s_fina then
-      setprop(last,a_state,s_fina)
-    else
-      warning(last,"fina")
-      setprop(last,a_state,s_error)
-    end
-  elseif first then
-    if c_first==s_medi or c_first==s_fina then
-      setprop(first,a_state,s_isol)
-    else
-      warning(first,"isol")
-      setprop(first,a_state,s_error)
-    end
-  end
-  return head,done
-end
-methods.syrc=methods.arab
-methods.mand=methods.arab
-methods.nko=methods.arab
-directives.register("otf.analyze.useunicodemarks",function(v)
-  analyzers.useunicodemarks=v
-end)
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-ota”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-ots” 7e1e55f9f728474372665e4a64a43f5a] ---
-
-if not modules then modules={} end modules ['font-ots']={ 
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files",
-}
-local type,next,tonumber=type,next,tonumber
-local random=math.random
-local formatters=string.formatters
-local insert=table.insert
-local logs,trackers,nodes,attributes=logs,trackers,nodes,attributes
-local registertracker=trackers.register
-local registerdirective=directives.register
-local fonts=fonts
-local otf=fonts.handlers.otf
-local trace_lookups=false registertracker("otf.lookups",function(v) trace_lookups=v end)
-local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end)
-local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end)
-local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end)
-local trace_ligatures=false registertracker("otf.ligatures",function(v) trace_ligatures=v end)
-local trace_contexts=false registertracker("otf.contexts",function(v) trace_contexts=v end)
-local trace_marks=false registertracker("otf.marks",function(v) trace_marks=v end)
-local trace_kerns=false registertracker("otf.kerns",function(v) trace_kerns=v end)
-local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursive=v end)
-local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end)
-local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end)
-local trace_details=false registertracker("otf.details",function(v) trace_details=v end)
-local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end)
-local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end)
-local trace_directions=false registertracker("otf.directions",function(v) trace_directions=v end)
-local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end)
-local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end)
-local trace_discruns=false registertracker("otf.discruns",function(v) trace_discruns=v end)
-local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end)
-local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end)
-local optimizekerns=true
-local alwaysdisc=true  registerdirective("otf.alwaysdisc",function(v) alwaysdisc=v end)
-local report_direct=logs.reporter("fonts","otf direct")
-local report_subchain=logs.reporter("fonts","otf subchain")
-local report_chain=logs.reporter("fonts","otf chain")
-local report_process=logs.reporter("fonts","otf process")
-local report_warning=logs.reporter("fonts","otf warning")
-local report_run=logs.reporter("fonts","otf run")
-registertracker("otf.replacements","otf.singles,otf.multiples,otf.alternatives,otf.ligatures")
-registertracker("otf.positions","otf.marks,otf.kerns,otf.cursive")
-registertracker("otf.actions","otf.replacements,otf.positions")
-registertracker("otf.injections","nodes.injections")
-registertracker("*otf.sample","otf.steps,otf.actions,otf.analyzing")
-local nuts=nodes.nuts
-local tonode=nuts.tonode
-local tonut=nuts.tonut
-local getfield=nuts.getfield
-local setfield=nuts.setfield
-local getnext=nuts.getnext
-local setnext=nuts.setnext
-local getprev=nuts.getprev
-local setprev=nuts.setprev
-local getboth=nuts.getboth
-local setboth=nuts.setboth
-local getid=nuts.getid
-local getattr=nuts.getattr
-local setattr=nuts.setattr
-local getprop=nuts.getprop
-local setprop=nuts.setprop
-local getfont=nuts.getfont
-local getsubtype=nuts.getsubtype
-local setsubtype=nuts.setsubtype
-local getchar=nuts.getchar
-local setchar=nuts.setchar
-local getdisc=nuts.getdisc
-local setdisc=nuts.setdisc
-local setlink=nuts.setlink
-local ischar=nuts.is_char
-local insert_node_after=nuts.insert_after
-local copy_node=nuts.copy
-local copy_node_list=nuts.copy_list
-local find_node_tail=nuts.tail
-local flush_node_list=nuts.flush_list
-local flush_node=nuts.flush_node
-local end_of_math=nuts.end_of_math
-local traverse_nodes=nuts.traverse
-local traverse_id=nuts.traverse_id
-local remove_node=nuts.remove
-local setmetatableindex=table.setmetatableindex
-local zwnj=0x200C
-local zwj=0x200D
-local wildcard="*"
-local default="dflt"
-local nodecodes=nodes.nodecodes
-local glyphcodes=nodes.glyphcodes
-local disccodes=nodes.disccodes
-local glyph_code=nodecodes.glyph
-local glue_code=nodecodes.glue
-local disc_code=nodecodes.disc
-local math_code=nodecodes.math
-local dir_code=nodecodes.dir
-local localpar_code=nodecodes.localpar
-local discretionary_code=disccodes.discretionary
-local ligature_code=glyphcodes.ligature
-local privateattribute=attributes.private
-local a_state=privateattribute('state')
-local injections=nodes.injections
-local setmark=injections.setmark
-local setcursive=injections.setcursive
-local setkern=injections.setkern
-local setpair=injections.setpair
-local resetinjection=injections.reset
-local copyinjection=injections.copy
-local setligaindex=injections.setligaindex
-local getligaindex=injections.getligaindex
-local cursonce=true
-local fonthashes=fonts.hashes
-local fontdata=fonthashes.identifiers
-local fontfeatures=fonthashes.features
-local otffeatures=fonts.constructors.features.otf
-local registerotffeature=otffeatures.register
-local onetimemessage=fonts.loggers.onetimemessage or function() end
-local getrandom=utilities and utilities.randomizer and utilities.randomizer.get
-otf.defaultnodealternate="none"
-local tfmdata=false
-local characters=false
-local descriptions=false
-local marks=false
-local currentfont=false
-local factor=0
-local threshold=0
-local checkmarks=false
-local sweepnode=nil
-local sweepprev=nil
-local sweepnext=nil
-local sweephead={}
-local notmatchpre={}
-local notmatchpost={}
-local notmatchreplace={}
-local handlers={}
-local isspace=injections.isspace
-local getthreshold=injections.getthreshold
-local checkstep=(nodes and nodes.tracers and nodes.tracers.steppers.check)  or function() end
-local registerstep=(nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end
-local registermessage=(nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end
-local function checkdisccontent(d)
-  local pre,post,replace=getdisc(d)
-  if pre   then for n in traverse_id(glue_code,pre)   do print("pre",nodes.idstostring(pre))   break end end
-  if post  then for n in traverse_id(glue_code,post)  do print("pos",nodes.idstostring(post))  break end end
-  if replace then for n in traverse_id(glue_code,replace) do print("rep",nodes.idstostring(replace)) break end end
-end
-local function logprocess(...)
-  if trace_steps then
-    registermessage(...)
-  end
-  report_direct(...)
-end
-local function logwarning(...)
-  report_direct(...)
-end
-local f_unicode=formatters["%U"]
-local f_uniname=formatters["%U (%s)"]
-local f_unilist=formatters["% t (% t)"]
-local function gref(n) 
-  if type(n)=="number" then
-    local description=descriptions[n]
-    local name=description and description.name
-    if name then
-      return f_uniname(n,name)
-    else
-      return f_unicode(n)
-    end
-  elseif n then
-    local num,nam={},{}
-    for i=1,#n do
-      local ni=n[i]
-      if tonumber(ni) then 
-        local di=descriptions[ni]
-        num[i]=f_unicode(ni)
-        nam[i]=di and di.name or "-"
-      end
-    end
-    return f_unilist(num,nam)
-  else
-    return "<error in node mode tracing>"
-  end
-end
-local function cref(dataset,sequence,index)
-  if not dataset then
-    return "no valid dataset"
-  elseif index then
-    return formatters["feature %a, type %a, chain lookup %a, index %a"](dataset[4],sequence.type,sequence.name,index)
-  else
-    return formatters["feature %a, type %a, chain lookup %a"](dataset[4],sequence.type,sequence.name)
-  end
-end
-local function pref(dataset,sequence)
-  return formatters["feature %a, type %a, lookup %a"](dataset[4],sequence.type,sequence.name)
-end
-local function mref(rlmode)
-  if not rlmode or rlmode==0 then
-    return "---"
-  elseif rlmode==-1 or rlmode=="+TRT" then
-    return "r2l"
-  else
-    return "l2r"
-  end
-end
-local function copy_glyph(g) 
-  local components=getfield(g,"components")
-  if components then
-    setfield(g,"components")
-    local n=copy_node(g)
-    copyinjection(n,g) 
-    setfield(g,"components",components)
-    return n
-  else
-    local n=copy_node(g)
-    copyinjection(n,g) 
-    return n
-  end
-end
-local function flattendisk(head,disc)
-  local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
-  local prev,next=getboth(disc)
-  local ishead=head==disc
-  setdisc(disc)
-  flush_node(disc)
-  if pre then
-    flush_node_list(pre)
-  end
-  if post then
-    flush_node_list(post)
-  end
-  if ishead then
-    if replace then
-      if next then
-        setlink(replacetail,next)
-      end
-      return replace,replace
-    elseif next then
-      return next,next
-    else
-      return 
-    end
-  else
-    if replace then
-      if next then
-        setlink(replacetail,next)
-      end
-      setlink(prev,replace)
-      return head,replace
-    else
-      setlink(prev,next) 
-      return head,next
-    end
-  end
-end
-local function appenddisc(disc,list)
-  local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
-  local posthead=list
-  local replacehead=copy_node_list(list)
-  if post then
-    setlink(posttail,posthead)
-  else
-    post=phead
-  end
-  if replace then
-    setlink(replacetail,replacehead)
-  else
-    replace=rhead
-  end
-  setdisc(disc,pre,post,replace)
-end
-local function markstoligature(head,start,stop,char)
-  if start==stop and getchar(start)==char then
-    return head,start
-  else
-    local prev=getprev(start)
-    local next=getnext(stop)
-    setprev(start)
-    setnext(stop)
-    local base=copy_glyph(start)
-    if head==start then
-      head=base
-    end
-    resetinjection(base)
-    setchar(base,char)
-    setsubtype(base,ligature_code)
-    setfield(base,"components",start)
-    setlink(prev,base)
-    setlink(base,next)
-    return head,base
-  end
-end
-local function getcomponentindex(start) 
-  if getid(start)~=glyph_code then 
-    return 0
-  elseif getsubtype(start)==ligature_code then
-    local i=0
-    local components=getfield(start,"components")
-    while components do
-      i=i+getcomponentindex(components)
-      components=getnext(components)
-    end
-    return i
-  elseif not marks[getchar(start)] then
-    return 1
-  else
-    return 0
-  end
-end
-local a_noligature=attributes.private("noligature")
-local function toligature(head,start,stop,char,dataset,sequence,markflag,discfound) 
-  if getattr(start,a_noligature)==1 then
-    return head,start
-  end
-  if start==stop and getchar(start)==char then
-    resetinjection(start)
-    setchar(start,char)
-    return head,start
-  end
-  local components=getfield(start,"components")
-  if components then
-  end
-  local prev=getprev(start)
-  local next=getnext(stop)
-  local comp=start
-  setprev(start)
-  setnext(stop)
-  local base=copy_glyph(start)
-  if start==head then
-    head=base
-  end
-  resetinjection(base)
-  setchar(base,char)
-  setsubtype(base,ligature_code)
-  setfield(base,"components",comp) 
-  if prev then
-    setnext(prev,base)
-  end
-  if next then
-    setprev(next,base)
-  end
-  setboth(base,prev,next)
-  if not discfound then
-    local deletemarks=markflag~="mark"
-    local components=start
-    local baseindex=0
-    local componentindex=0
-    local head=base
-    local current=base
-    while start do
-      local char=getchar(start)
-      if not marks[char] then
-        baseindex=baseindex+componentindex
-        componentindex=getcomponentindex(start)
-      elseif not deletemarks then 
-        setligaindex(start,baseindex+getligaindex(start,componentindex))
-        if trace_marks then
-          logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
-        end
-        local n=copy_node(start)
-        copyinjection(n,start)
-        head,current=insert_node_after(head,current,n) 
-      elseif trace_marks then
-        logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char))
-      end
-      start=getnext(start)
-    end
-    local start=getnext(current)
-    while start do
-      local char=ischar(start)
-      if char then
-        if marks[char] then
-          setligaindex(start,baseindex+getligaindex(start,componentindex))
-          if trace_marks then
-            logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
-          end
-          start=getnext(start)
-        else
-          break
-        end
-      else
-        break
-      end
-    end
-  else
-    local discprev,discnext=getboth(discfound)
-    if discprev and discnext then
-      local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true)
-      if not replace then 
-        local prev=getprev(base)
-        local current=comp
-        local previous=nil
-        local copied=nil
-        while current do
-          if getid(current)==glyph_code then
-            local n=copy_node(current)
-            if copied then
-              setlink(previous,n)
-            else
-              copied=n
-            end
-            previous=n
-          end
-          current=getnext(current)
-        end
-        setprev(discnext) 
-        setnext(discprev) 
-        if pre then
-          setlink(discprev,pre)
-        end
-        pre=comp
-        if post then
-          setlink(posttail,discnext)
-          setprev(post)
-        else
-          post=discnext
-        end
-        setlink(prev,discfound)
-        setlink(discfound,next)
-        setboth(base)
-        setfield(base,"components",copied)
-        setdisc(discfound,pre,post,base) 
-        base=prev 
-      end
-    end
-  end
-  return head,base
-end
-local function multiple_glyphs(head,start,multiple,ignoremarks,what)
-  local nofmultiples=#multiple
-  if nofmultiples>0 then
-    resetinjection(start)
-    setchar(start,multiple[1])
-    if nofmultiples>1 then
-      local sn=getnext(start)
-      for k=2,nofmultiples do
-        local n=copy_node(start) 
-        resetinjection(n)
-        setchar(n,multiple[k])
-        insert_node_after(head,start,n)
-        start=n
-      end
-      if what==true then
-      elseif what>1 then
-        local m=multiple[nofmultiples]
-        for i=2,what do
-          local n=copy_node(start) 
-          resetinjection(n)
-          setchar(n,m)
-          insert_node_after(head,start,n)
-          start=n
-        end
-      end
-    end
-    return head,start,true
-  else
-    if trace_multiples then
-      logprocess("no multiple for %s",gref(getchar(start)))
-    end
-    return head,start,false
-  end
-end
-local function get_alternative_glyph(start,alternatives,value)
-  local n=#alternatives
-  if value=="random" then
-    local r=getrandom and getrandom("glyph",1,n) or random(1,n)
-    return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r)
-  elseif value=="first" then
-    return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1)
-  elseif value=="last" then
-    return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n)
-  end
-  value=value==true and 1 or tonumber(value)
-  if type(value)~="number" then
-    return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
-  end
-  if value>n then
-    local defaultalt=otf.defaultnodealternate
-    if defaultalt=="first" then
-      return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
-    elseif defaultalt=="last" then
-      return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n)
-    else
-      return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range")
-    end
-  elseif value==0 then
-    return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change")
-  elseif value<1 then
-    return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1)
-  else
-    return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value)
-  end
-end
-function handlers.gsub_single(head,start,dataset,sequence,replacement)
-  if trace_singles then
-    logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement))
-  end
-  resetinjection(start)
-  setchar(start,replacement)
-  return head,start,true
-end
-function handlers.gsub_alternate(head,start,dataset,sequence,alternative)
-  local kind=dataset[4]
-  local what=dataset[1]
-  local value=what==true and tfmdata.shared.features[kind] or what
-  local choice,comment=get_alternative_glyph(start,alternative,value)
-  if choice then
-    if trace_alternatives then
-      logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment)
-    end
-    resetinjection(start)
-    setchar(start,choice)
-  else
-    if trace_alternatives then
-      logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment)
-    end
-  end
-  return head,start,true
-end
-function handlers.gsub_multiple(head,start,dataset,sequence,multiple)
-  if trace_multiples then
-    logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple))
-  end
-  return multiple_glyphs(head,start,multiple,sequence.flags[1],dataset[1])
-end
-function handlers.gsub_ligature(head,start,dataset,sequence,ligature)
-  local current=getnext(start)
-  if not current then
-    return head,start,false,nil
-  end
-  local stop=nil
-  local startchar=getchar(start)
-  if marks[startchar] then
-    while current do
-      local char=ischar(current,currentfont)
-      if char then
-        local lg=ligature[char]
-        if lg then
-          stop=current
-          ligature=lg
-          current=getnext(current)
-        else
-          break
-        end
-      else
-        break
-      end
-    end
-    if stop then
-      local lig=ligature.ligature
-      if lig then
-        if trace_ligatures then
-          local stopchar=getchar(stop)
-          head,start=markstoligature(head,start,stop,lig)
-          logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start)))
-        else
-          head,start=markstoligature(head,start,stop,lig)
-        end
-        return head,start,true,false
-      else
-      end
-    end
-  else
-    local skipmark=sequence.flags[1]
-    local discfound=false
-    local lastdisc=nil
-    while current do
-      local char,id=ischar(current,currentfont)
-      if char then
-        if skipmark and marks[char] then
-          current=getnext(current)
-        else 
-          local lg=ligature[char] 
-          if lg then
-            if not discfound and lastdisc then
-              discfound=lastdisc
-              lastdisc=nil
-            end
-            stop=current 
-            ligature=lg
-            current=getnext(current)
-          else
-            break
-          end
-        end
-      elseif char==false then
-        break
-      elseif id==disc_code then
-        local replace=getfield(current,"replace")
-        if replace then
-          while replace do
-            local char,id=ischar(replace,currentfont)
-            if char then
-              local lg=ligature[char] 
-              if lg then
-                ligature=lg
-                replace=getnext(replace)
-              else
-                return head,start,false,false
-              end
-            else
-              return head,start,false,false
-            end
-          end
-          stop=current
-        end
-        lastdisc=current
-        current=getnext(current)
-      else
-        break
-      end
-    end
-    local lig=ligature.ligature
-    if lig then
-      if stop then
-        if trace_ligatures then
-          local stopchar=getchar(stop)
-          head,start=toligature(head,start,stop,lig,dataset,sequence,skipmark,discfound)
-          logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
-        else
-          head,start=toligature(head,start,stop,lig,dataset,sequence,skipmark,discfound)
-        end
-      else
-        resetinjection(start)
-        setchar(start,lig)
-        if trace_ligatures then
-          logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig))
-        end
-      end
-      return head,start,true,discfound
-    else
-    end
-  end
-  return head,start,false,discfound
-end
-function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,step,i,injection)
-  local startchar=getchar(start)
-  if step.format=="pair" then
-    local dx,dy,w,h=setpair(start,factor,rlmode,sequence.flags[4],kerns,injection)
-    if trace_kerns then
-      logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(dataset,sequence),gref(startchar),dx,dy,w,h)
-    end
-  else
-    local k=setkern(start,factor,rlmode,kerns,injection)
-    if trace_kerns then
-      logprocess("%s: shifting single %s by %p",pref(dataset,sequence),gref(startchar),k)
-    end
-  end
-  return head,start,false
-end
-function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,step,i,injection)
-  local snext=getnext(start)
-  if not snext then
-    return head,start,false
-  else
-    local prev=start
-    local done=false
-    while snext do
-      local nextchar=ischar(snext,currentfont)
-      if nextchar then
-        local krn=kerns[nextchar]
-        if not krn and marks[nextchar] then
-          prev=snext
-          snext=getnext(snext)
-        elseif not krn then
-          break
-        elseif step.format=="pair" then
-          local a,b=krn[1],krn[2]
-          if optimizekerns then
-            if not b and a[1]==0 and a[2]==0 and a[4]==0 then
-              local k=setkern(snext,factor,rlmode,a[3],injection)
-              if trace_kerns then
-                logprocess("%s: shifting single %s by %p",pref(dataset,sequence),gref(nextchar),k)
-              end
-              done=true
-              break
-            end
-          end
-          if a and #a>0 then
-            local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,injection)
-            if trace_kerns then
-              local startchar=getchar(start)
-              logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
-            end
-          end
-          if b and #b>0 then
-            local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,injection)
-            if trace_kerns then
-              local startchar=getchar(snext)
-              logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
-            end
-          end
-          done=true
-          break
-        elseif krn~=0 then
-          local k=setkern(snext,factor,rlmode,krn,injection)
-          if trace_kerns then
-            logprocess("%s: inserting kern %p between %s and %s as %s",pref(dataset,sequence),k,gref(getchar(prev)),gref(nextchar),injection or "injections")
-          end
-          done=true
-          break
-        else 
-          break
-        end
-      else
-        break
-      end
-    end
-    return head,start,done
-  end
-end
-function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode)
-  local markchar=getchar(start)
-  if marks[markchar] then
-    local base=getprev(start) 
-    if base then
-      local basechar=ischar(base,currentfont)
-      if basechar then
-        if marks[basechar] then
-          while base do
-            base=getprev(base)
-            if base then
-              basechar=ischar(base,currentfont)
-              if basechar then
-                if not marks[basechar] then
-                  break
-                end
-              else
-                if trace_bugs then
-                  logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
-                end
-                return head,start,false
-              end
-            else
-              if trace_bugs then
-                logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
-              end
-              return head,start,false
-            end
-          end
-        end
-        local ba=markanchors[1][basechar]
-        if ba then
-          local ma=markanchors[2]
-          local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
-          if trace_marks then
-            logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)",
-              pref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy)
-          end
-          return head,start,true
-        end
-      elseif trace_bugs then
-        logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1)
-      end
-    elseif trace_bugs then
-      logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2)
-    end
-  elseif trace_bugs then
-    logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
-  end
-  return head,start,false
-end
-function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlmode)
-  local markchar=getchar(start)
-  if marks[markchar] then
-    local base=getprev(start) 
-    if base then
-      local basechar=ischar(base,currentfont)
-      if basechar then
-        if marks[basechar] then
-          while base do
-            base=getprev(base)
-            if base then
-              basechar=ischar(base,currentfont)
-              if basechar then
-                if not marks[basechar] then
-                  break
-                end
-              else
-                if trace_bugs then
-                  logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
-                end
-                return head,start,false
-              end
-            else
-              if trace_bugs then
-                logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
-              end
-              return head,start,false
-            end
-          end
-        end
-        local ba=markanchors[1][basechar]
-        if ba then
-          local ma=markanchors[2]
-          if ma then
-            local index=getligaindex(start)
-            ba=ba[index]
-            if ba then
-              local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
-              if trace_marks then
-                logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)",
-                  pref(dataset,sequence),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy)
-              end
-              return head,start,true
-            else
-              if trace_bugs then
-                logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index)
-              end
-            end
-          end
-        elseif trace_bugs then
-          onetimemessage(currentfont,basechar,"no base anchors",report_fonts)
-        end
-      elseif trace_bugs then
-        logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1)
-      end
-    elseif trace_bugs then
-      logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2)
-    end
-  elseif trace_bugs then
-    logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
-  end
-  return head,start,false
-end
-function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode)
-  local markchar=getchar(start)
-  if marks[markchar] then
-    local base=getprev(start) 
-    local slc=getligaindex(start)
-    if slc then 
-      while base do
-        local blc=getligaindex(base)
-        if blc and blc~=slc then
-          base=getprev(base)
-        else
-          break
-        end
-      end
-    end
-    if base then
-      local basechar=ischar(base,currentfont)
-      if basechar then 
-        local ba=markanchors[1][basechar] 
-        if ba then
-          local ma=markanchors[2]
-          local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
-          if trace_marks then
-            logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)",
-              pref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy)
-          end
-          return head,start,true
-        end
-      end
-    end
-  elseif trace_bugs then
-    logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
-  end
-  return head,start,false
-end
-function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,step,i) 
-  local done=false
-  local startchar=getchar(start)
-  if marks[startchar] then
-    if trace_cursive then
-      logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
-    end
-  else
-    local nxt=getnext(start)
-    while not done and nxt do
-      local nextchar=ischar(nxt,currentfont)
-      if not nextchar then
-        break
-      elseif marks[nextchar] then
-        nxt=getnext(nxt)
-      else
-        local exit=exitanchors[3]
-        if exit then
-          local entry=exitanchors[1][nextchar]
-          if entry then
-            entry=entry[2]
-            if entry then
-              local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
-              if trace_cursive then
-                logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,anchor,bound,mref(rlmode))
-              end
-              done=true
-            end
-          end
-        end
-        break
-      end
-    end
-  end
-  return head,start,done
-end
-local chainprocs={}
-local function logprocess(...)
-  if trace_steps then
-    registermessage(...)
-  end
-  report_subchain(...)
-end
-local logwarning=report_subchain
-local function logprocess(...)
-  if trace_steps then
-    registermessage(...)
-  end
-  report_chain(...)
-end
-local logwarning=report_chain
-local function reversesub(head,start,stop,dataset,sequence,replacements,rlmode)
-  local char=getchar(start)
-  local replacement=replacements[char]
-  if replacement then
-    if trace_singles then
-      logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement))
-    end
-    resetinjection(start)
-    setchar(start,replacement)
-    return head,start,true
-  else
-    return head,start,false
-  end
-end
-chainprocs.reversesub=reversesub
-local function reportmoresteps(dataset,sequence)
-  logwarning("%s: more than 1 step",cref(dataset,sequence))
-end
-function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,chainindex)
-  local steps=currentlookup.steps
-  local nofsteps=currentlookup.nofsteps
-  if nofsteps>1 then
-    reportmoresteps(dataset,sequence)
-  end
-  local current=start
-  while current do
-    local currentchar=ischar(current)
-    if currentchar then
-      local replacement=steps[1].coverage[currentchar]
-      if not replacement or replacement=="" then
-        if trace_bugs then
-          logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar))
-        end
-      else
-        if trace_singles then
-          logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement))
-        end
-        resetinjection(current)
-        setchar(current,replacement)
-      end
-      return head,start,true
-    elseif currentchar==false then
-      break
-    elseif current==stop then
-      break
-    else
-      current=getnext(current)
-    end
-  end
-  return head,start,false
-end
-function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup)
-  local steps=currentlookup.steps
-  local nofsteps=currentlookup.nofsteps
-  if nofsteps>1 then
-    reportmoresteps(dataset,sequence)
-  end
-  local startchar=getchar(start)
-  local replacement=steps[1].coverage[startchar]
-  if not replacement or replacement=="" then
-    if trace_bugs then
-      logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar))
-    end
-  else
-    if trace_multiples then
-      logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement))
-    end
-    return multiple_glyphs(head,start,replacement,sequence.flags[1],dataset[1])
-  end
-  return head,start,false
-end
-function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlookup)
-  local steps=currentlookup.steps
-  local nofsteps=currentlookup.nofsteps
-  if nofsteps>1 then
-    reportmoresteps(dataset,sequence)
-  end
-  local kind=dataset[4]
-  local what=dataset[1]
-  local value=what==true and tfmdata.shared.features[kind] or what 
-  local current=start
-  while current do
-    local currentchar=ischar(current)
-    if currentchar then
-      local alternatives=steps[1].coverage[currentchar]
-      if alternatives then
-        local choice,comment=get_alternative_glyph(current,alternatives,value)
-        if choice then
-          if trace_alternatives then
-            logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(char),choice,gref(choice),comment)
-          end
-          resetinjection(start)
-          setchar(start,choice)
-        else
-          if trace_alternatives then
-            logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(char),comment)
-          end
-        end
-      end
-      return head,start,true
-    elseif currentchar==false then
-      break
-    elseif current==stop then
-      break
-    else
-      current=getnext(current)
-    end
-  end
-  return head,start,false
-end
-function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,chainindex)
-  local steps=currentlookup.steps
-  local nofsteps=currentlookup.nofsteps
-  if nofsteps>1 then
-    reportmoresteps(dataset,sequence)
-  end
-  local startchar=getchar(start)
-  local ligatures=steps[1].coverage[startchar]
-  if not ligatures then
-    if trace_bugs then
-      logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar))
-    end
-  else
-    local current=getnext(start)
-    local discfound=false
-    local last=stop
-    local nofreplacements=1
-    local skipmark=currentlookup.flags[1] 
-    while current do
-      local id=getid(current)
-      if id==disc_code then
-        if not discfound then
-          discfound=current
-        end
-        if current==stop then
-          break 
-        else
-          current=getnext(current)
-        end
-      else
-        local schar=getchar(current)
-        if skipmark and marks[schar] then
-            current=getnext(current)
-        else
-          local lg=ligatures[schar]
-          if lg then
-            ligatures=lg
-            last=current
-            nofreplacements=nofreplacements+1
-            if current==stop then
-              break
-            else
-              current=getnext(current)
-            end
-          else
-            break
-          end
-        end
-      end
-    end
-    local ligature=ligatures.ligature
-    if ligature then
-      if chainindex then
-        stop=last
-      end
-      if trace_ligatures then
-        if start==stop then
-          logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature))
-        else
-          logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature))
-        end
-      end
-      head,start=toligature(head,start,stop,ligature,dataset,sequence,skipmark,discfound)
-      return head,start,true,nofreplacements,discfound
-    elseif trace_bugs then
-      if start==stop then
-        logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar))
-      else
-        logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)))
-      end
-    end
-  end
-  return head,start,false,0,false
-end
-function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,chainindex)
-  local steps=currentlookup.steps
-  local nofsteps=currentlookup.nofsteps
-  if nofsteps>1 then
-    reportmoresteps(dataset,sequence)
-  end
-  local startchar=getchar(start)
-  local step=steps[1]
-  local kerns=step.coverage[startchar]
-  if not kerns then
-  elseif step.format=="pair" then
-    local dx,dy,w,h=setpair(start,factor,rlmode,sequence.flags[4],kerns) 
-    if trace_kerns then
-      logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),dx,dy,w,h)
-    end
-  else 
-    local k=setkern(start,factor,rlmode,kerns,injection)
-    if trace_kerns then
-      logprocess("%s: shifting single %s by %p",cref(dataset,sequence),gref(startchar),k)
-    end
-  end
-  return head,start,false
-end
-function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,chainindex) 
-  local steps=currentlookup.steps
-  local nofsteps=currentlookup.nofsteps
-  if nofsteps>1 then
-    reportmoresteps(dataset,sequence)
-  end
-  local snext=getnext(start)
-  if snext then
-    local startchar=getchar(start)
-    local step=steps[1]
-    local kerns=step.coverage[startchar] 
-    if kerns then
-      local prev=start
-      local done=false
-      while snext do
-        local nextchar=ischar(snext,currentfont)
-        if not nextchar then
-          break
-        end
-        local krn=kerns[nextchar]
-        if not krn and marks[nextchar] then
-          prev=snext
-          snext=getnext(snext)
-        elseif not krn then
-          break
-        elseif step.format=="pair" then
-          local a,b=krn[1],krn[2]
-          if optimizekerns then
-            if not b and a[1]==0 and a[2]==0 and a[4]==0 then
-              local k=setkern(snext,factor,rlmode,a[3],"injections")
-              if trace_kerns then
-                logprocess("%s: shifting single %s by %p",cref(dataset,sequence),gref(startchar),k)
-              end
-              done=true
-              break
-            end
-          end
-          if a and #a>0 then
-            local startchar=getchar(start)
-            local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,"injections") 
-            if trace_kerns then
-              logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
-            end
-          end
-          if b and #b>0 then
-            local startchar=getchar(start)
-            local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,"injections")
-            if trace_kerns then
-              logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
-            end
-          end
-          done=true
-          break
-        elseif krn~=0 then
-          local k=setkern(snext,factor,rlmode,krn)
-          if trace_kerns then
-            logprocess("%s: inserting kern %s between %s and %s",cref(dataset,sequence),k,gref(getchar(prev)),gref(nextchar))
-          end
-          done=true
-          break
-        else
-          break
-        end
-      end
-      return head,start,done
-    end
-  end
-  return head,start,false
-end
-function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode)
-  local steps=currentlookup.steps
-  local nofsteps=currentlookup.nofsteps
-  if nofsteps>1 then
-    reportmoresteps(dataset,sequence)
-  end
-  local markchar=getchar(start)
-  if marks[markchar] then
-    local markanchors=steps[1].coverage[markchar] 
-    if markanchors then
-      local base=getprev(start) 
-      if base then
-        local basechar=ischar(base,currentfont)
-        if basechar then
-          if marks[basechar] then
-            while base do
-              base=getprev(base)
-              if base then
-                local basechar=ischar(base,currentfont)
-                if basechar then
-                  if not marks[basechar] then
-                    break
-                  end
-                else
-                  if trace_bugs then
-                    logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
-                  end
-                  return head,start,false
-                end
-              else
-                if trace_bugs then
-                  logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
-                end
-                return head,start,false
-              end
-            end
-          end
-          local ba=markanchors[1][basechar]
-          if ba then
-            local ma=markanchors[2]
-            if ma then
-              local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
-              if trace_marks then
-                logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)",
-                  cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy)
-              end
-              return head,start,true
-            end
-          end
-        elseif trace_bugs then
-          logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1)
-        end
-      elseif trace_bugs then
-        logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2)
-      end
-    elseif trace_bugs then
-      logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
-    end
-  elseif trace_bugs then
-    logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
-  end
-  return head,start,false
-end
-function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentlookup,rlmode)
-  local steps=currentlookup.steps
-  local nofsteps=currentlookup.nofsteps
-  if nofsteps>1 then
-    reportmoresteps(dataset,sequence)
-  end
-  local markchar=getchar(start)
-  if marks[markchar] then
-    local markanchors=steps[1].coverage[markchar] 
-    if markanchors then
-      local base=getprev(start) 
-      if base then
-        local basechar=ischar(base,currentfont)
-        if basechar then
-          if marks[basechar] then
-            while base do
-              base=getprev(base)
-              if base then
-                local basechar=ischar(base,currentfont)
-                if basechar then
-                  if not marks[basechar] then
-                    break
-                  end
-                else
-                  if trace_bugs then
-                    logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1)
-                  end
-                  return head,start,false
-                end
-              else
-                if trace_bugs then
-                  logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2)
-                end
-                return head,start,false
-              end
-            end
-          end
-          local ba=markanchors[1][basechar]
-          if ba then
-            local ma=markanchors[2]
-            if ma then
-              local index=getligaindex(start)
-              ba=ba[index]
-              if ba then
-                local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
-                if trace_marks then
-                  logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)",
-                    cref(dataset,sequence),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy)
-                end
-                return head,start,true
-              end
-            end
-          end
-        elseif trace_bugs then
-          logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1)
-        end
-      elseif trace_bugs then
-        logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2)
-      end
-    elseif trace_bugs then
-      logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar))
-    end
-  elseif trace_bugs then
-    logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar))
-  end
-  return head,start,false
-end
-function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlookup,rlmode)
-  local steps=currentlookup.steps
-  local nofsteps=currentlookup.nofsteps
-  if nofsteps>1 then
-    reportmoresteps(dataset,sequence)
-  end
-  local markchar=getchar(start)
-  if marks[markchar] then
-    local markanchors=steps[1].coverage[markchar] 
-    if markanchors then
-      local base=getprev(start) 
-      local slc=getligaindex(start)
-      if slc then 
-        while base do
-          local blc=getligaindex(base)
-          if blc and blc~=slc then
-            base=getprev(base)
-          else
-            break
-          end
-        end
-      end
-      if base then 
-        local basechar=ischar(base,currentfont)
-        if basechar then
-          local ba=markanchors[1][basechar]
-          if ba then
-            local ma=markanchors[2]
-            if ma then
-              local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
-              if trace_marks then
-                logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)",
-                  cref(dataset,sequence),anchor,bound,gref(markchar),gref(basechar),dx,dy)
-              end
-              return head,start,true
-            end
-          end
-        elseif trace_bugs then
-          logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1)
-        end
-      elseif trace_bugs then
-        logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2)
-      end
-    elseif trace_bugs then
-      logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
-    end
-  elseif trace_bugs then
-    logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
-  end
-  return head,start,false
-end
-function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,rlmode)
-  local steps=currentlookup.steps
-  local nofsteps=currentlookup.nofsteps
-  if nofsteps>1 then
-    reportmoresteps(dataset,sequence)
-  end
-  local startchar=getchar(start)
-  local exitanchors=steps[1].coverage[startchar] 
-  if exitanchors then
-    local done=false
-    if marks[startchar] then
-      if trace_cursive then
-        logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
-      end
-    else
-      local nxt=getnext(start)
-      while not done and nxt do
-        local nextchar=ischar(nxt,currentfont)
-        if not nextchar then
-          break
-        elseif marks[nextchar] then
-          nxt=getnext(nxt)
-        else
-          local exit=exitanchors[3]
-          if exit then
-            local entry=exitanchors[1][nextchar]
-            if entry then
-              entry=entry[2]
-              if entry then
-                local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
-                if trace_cursive then
-                  logprocess("%s: moving %s to %s cursive (%p,%p) using anchor %s and bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,anchor,bound,mref(rlmode))
-                end
-                done=true
-                break
-              end
-            end
-          elseif trace_bugs then
-            onetimemessage(currentfont,startchar,"no entry anchors",report_fonts)
-          end
-          break
-        end
-      end
-    end
-    return head,start,done
-  else
-    if trace_cursive and trace_details then
-      logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone)
-    end
-    return head,start,false
-  end
-end
-local function show_skip(dataset,sequence,char,ck,class)
-  logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2])
-end
-local new_kern=nuts.pool.kern
-local function checked(head)
-  local current=head
-  while current do
-    if getid(current)==glue_code then
-      local kern=new_kern(getfield(current,"width"))
-      if head==current then
-        local next=getnext(current)
-        if next then
-          setlink(kern,next)
-        end
-        flush_node(current)
-        head=kern
-        current=next
-      else
-        local prev,next=getboth(current)
-        setlink(prev,kern)
-        setlink(kern,next)
-        flush_node(current)
-        current=next
-      end
-    else
-      current=getnext(current)
-    end
-  end
-  return head
-end
-local function setdiscchecked(d,pre,post,replace)
-  if pre   then pre=checked(pre)   end
-  if post  then post=checked(post)  end
-  if replace then replace=checked(replace) end
-  setdisc(d,pre,post,replace)
-end
-local function chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,k,ck,chainproc)
-  if not start then
-    return head,start,false
-  end
-  local startishead=start==head
-  local seq=ck[3]
-  local f=ck[4]
-  local l=ck[5]
-  local s=#seq
-  local done=false
-  local sweepnode=sweepnode
-  local sweeptype=sweeptype
-  local sweepoverflow=false
-  local checkdisc=getprev(head) 
-  local keepdisc=not sweepnode
-  local lookaheaddisc=nil
-  local backtrackdisc=nil
-  local current=start
-  local last=start
-  local prev=getprev(start)
-  local hasglue=false
-  local i=f
-  while i<=l do
-    local id=getid(current)
-    if id==glyph_code then
-      i=i+1
-      last=current
-      current=getnext(current)
-    elseif id==glue_code then
-      i=i+1
-      last=current
-      current=getnext(current)
-      hasglue=true
-    elseif id==disc_code then
-      if keepdisc then
-        keepdisc=false
-        if notmatchpre[current]~=notmatchreplace[current] then
-          lookaheaddisc=current
-        end
-        local replace=getfield(current,"replace")
-        while replace and i<=l do
-          if getid(replace)==glyph_code then
-            i=i+1
-          end
-          replace=getnext(replace)
-        end
-        last=current
-        current=getnext(c)
-      else
-        head,current=flattendisk(head,current)
-      end
-    else
-      last=current
-      current=getnext(current)
-    end
-    if current then
-    elseif sweepoverflow then
-      break
-    elseif sweeptype=="post" or sweeptype=="replace" then
-      current=getnext(sweepnode)
-      if current then
-        sweeptype=nil
-        sweepoverflow=true
-      else
-        break
-      end
-    else
-      break 
-    end
-  end
-  if sweepoverflow then
-    local prev=current and getprev(current)
-    if not current or prev~=sweepnode then
-      local head=getnext(sweepnode)
-      local tail=nil
-      if prev then
-        tail=prev
-        setprev(current,sweepnode)
-      else
-        tail=find_node_tail(head)
-      end
-      setnext(sweepnode,current)
-      setprev(head)
-      setnext(tail)
-      appenddisc(sweepnode,head)
-    end
-  end
-  if l<s then
-    local i=l
-    local t=sweeptype=="post" or sweeptype=="replace"
-    while current and i<s do
-      local id=getid(current)
-      if id==glyph_code then
-        i=i+1
-        current=getnext(current)
-      elseif id==glue_code then
-        i=i+1
-        current=getnext(current)
-        hasglue=true
-      elseif id==disc_code then
-        if keepdisc then
-          keepdisc=false
-          if notmatchpre[current]~=notmatchreplace[current] then
-            lookaheaddisc=current
-          end
-          local replace=getfield(c,"replace")
-          while replace and i<s do
-            if getid(replace)==glyph_code then
-              i=i+1
-            end
-            replace=getnext(replace)
-          end
-          current=getnext(current)
-        elseif notmatchpre[current]~=notmatchreplace[current] then
-          head,current=flattendisk(head,current)
-        else
-          current=getnext(current) 
-        end
-      else
-        current=getnext(current)
-      end
-      if not current and t then
-        current=getnext(sweepnode)
-        if current then
-          sweeptype=nil
-        end
-      end
-    end
-  end
-  if f>1 then
-    local current=prev
-    local i=f
-    local t=sweeptype=="pre" or sweeptype=="replace"
-    if not current and t and current==checkdisk then
-      current=getprev(sweepnode)
-    end
-    while current and i>1 do 
-      local id=getid(current)
-      if id==glyph_code then
-        i=i-1
-      elseif id==glue_code then
-        i=i-1
-        hasglue=true
-      elseif id==disc_code then
-        if keepdisc then
-          keepdisc=false
-          if notmatchpost[current]~=notmatchreplace[current] then
-            backtrackdisc=current
-          end
-          local replace=getfield(current,"replace")
-          while replace and i>1 do
-            if getid(replace)==glyph_code then
-              i=i-1
-            end
-            replace=getnext(replace)
-          end
-        elseif notmatchpost[current]~=notmatchreplace[current] then
-          head,current=flattendisk(head,current)
-        end
-      end
-      current=getprev(current)
-      if t and current==checkdisk then
-        current=getprev(sweepnode)
-      end
-    end
-  end
-  local ok=false
-  if lookaheaddisc then
-    local cf=start
-    local cl=getprev(lookaheaddisc)
-    local cprev=getprev(start)
-    local insertedmarks=0
-    while cprev do
-      local char=ischar(cf,currentfont)
-      if char and marks[char] then
-        insertedmarks=insertedmarks+1
-        cf=cprev
-        startishead=cf==head
-        cprev=getprev(cprev)
-      else
-        break
-      end
-    end
-    setprev(lookaheaddisc,cprev)
-    if cprev then
-      setnext(cprev,lookaheaddisc)
-    end
-    setprev(cf)
-    setnext(cl)
-    if startishead then
-      head=lookaheaddisc
-    end
-    local pre,post,replace=getdisc(lookaheaddisc)
-    local new=copy_node_list(cf)
-    local cnew=new
-    for i=1,insertedmarks do
-      cnew=getnext(cnew)
-    end
-    local clast=cnew
-    for i=f,l do
-      clast=getnext(clast)
-    end
-    if not notmatchpre[lookaheaddisc] then
-      cf,start,ok=chainproc(cf,start,last,dataset,sequence,chainlookup,rlmode,k)
-    end
-    if not notmatchreplace[lookaheaddisc] then
-      new,cnew,ok=chainproc(new,cnew,clast,dataset,sequence,chainlookup,rlmode,k)
-    end
-    if pre then
-      setlink(cl,pre)
-    end
-    if replace then
-      local tail=find_node_tail(new)
-      setlink(tail,replace)
-    end
-    if hasglue then
-      setdiscchecked(lookaheaddisc,cf,post,new)
-    else
-      setdisc(lookaheaddisc,cf,post,new)
-    end
-    start=getprev(lookaheaddisc)
-    sweephead[cf]=getnext(clast)
-    sweephead[new]=getnext(last)
-  elseif backtrackdisc then
-    local cf=getnext(backtrackdisc)
-    local cl=start
-    local cnext=getnext(start)
-    local insertedmarks=0
-    while cnext do
-      local char=ischar(cnext,currentfont)
-      if char and marks[char] then
-        insertedmarks=insertedmarks+1
-        cl=cnext
-        cnext=getnext(cnext)
-      else
-        break
-      end
-    end
-    if cnext then
-      setprev(cnext,backtrackdisc)
-    end
-    setnext(backtrackdisc,cnext)
-    setprev(cf)
-    setnext(cl)
-    local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true)
-    local new=copy_node_list(cf)
-    local cnew=find_node_tail(new)
-    for i=1,insertedmarks do
-      cnew=getprev(cnew)
-    end
-    local clast=cnew
-    for i=f,l do
-      clast=getnext(clast)
-    end
-    if not notmatchpost[backtrackdisc] then
-      cf,start,ok=chainproc(cf,start,last,dataset,sequence,chainlookup,rlmode,k)
-    end
-    if not notmatchreplace[backtrackdisc] then
-      new,cnew,ok=chainproc(new,cnew,clast,dataset,sequence,chainlookup,rlmode,k)
-    end
-    if post then
-      setlink(posttail,cf)
-    else
-      post=cf
-    end
-    if replace then
-      setlink(replacetail,new)
-    else
-      replace=new
-    end
-    if hasglue then
-      setdiscchecked(backtrackdisc,pre,post,replace)
-    else
-      setdisc(backtrackdisc,pre,post,replace)
-    end
-    start=getprev(backtrackdisc)
-    sweephead[post]=getnext(clast)
-    sweephead[replace]=getnext(last)
-  else
-    head,start,ok=chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,k)
-  end
-  return head,start,ok
-end
-local noflags={ false,false,false,false }
-local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode)
-  local sweepnode=sweepnode
-  local sweeptype=sweeptype
-  local currentfont=currentfont
-  local diskseen=false
-  local checkdisc=getprev(head)
-  local flags=sequence.flags or noflags
-  local done=false
-  local skipmark=flags[1]
-  local skipligature=flags[2]
-  local skipbase=flags[3]
-  local markclass=sequence.markclass
-  local skipped=false
-  for k=1,#contexts do 
-    local match=true
-    local current=start
-    local last=start
-    local ck=contexts[k]
-    local seq=ck[3]
-    local s=#seq
-    local size=1
-    if s==1 then
-      local char=ischar(current,currentfont)
-      if char then
-        match=seq[1][char]
-      end
-    else
-      local f=ck[4]
-      local l=ck[5]
-      size=l-f+1
-      if size>1 then
-        local discfound=nil
-        local n=f+1
-        last=getnext(last) 
-        while n<=l do
-          if not last and (sweeptype=="post" or sweeptype=="replace") then
-            last=getnext(sweepnode)
-            sweeptype=nil
-          end
-          if last then
-            local char,id=ischar(last,currentfont)
-            if char then
-              local ccd=descriptions[char]
-              if ccd then
-                local class=ccd.class or "base"
-                if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then
-                  skipped=true
-                  if trace_skips then
-                    show_skip(dataset,sequence,char,ck,class)
-                  end
-                  last=getnext(last)
-                elseif seq[n][char] then
-                  if n<l then
-                    last=getnext(last)
-                  end
-                  n=n+1
-                else
-                  if discfound then
-                    notmatchreplace[discfound]=true
-                    match=not notmatchpre[discfound]
-                  else
-                    match=false
-                  end
-                  break
-                end
-              else
-                if discfound then
-                  notmatchreplace[discfound]=true
-                  match=not notmatchpre[discfound]
-                else
-                  match=false
-                end
-                break
-              end
-            elseif char==false then
-              if discfound then
-                notmatchreplace[discfound]=true
-                match=not notmatchpre[discfound]
-              else
-                match=false
-              end
-              break
-            elseif id==disc_code then
-              diskseen=true
-              discfound=last
-              notmatchpre[last]=nil
-              notmatchpost[last]=true
-              notmatchreplace[last]=nil
-              local pre,post,replace=getdisc(last)
-              if pre then
-                local n=n
-                while pre do
-                  if seq[n][getchar(pre)] then
-                    n=n+1
-                    pre=getnext(pre)
-                    if n>l then
-                      break
-                    end
-                  else
-                    notmatchpre[last]=true
-                    break
-                  end
-                end
-                if n<=l then
-                  notmatchpre[last]=true
-                end
-              else
-                notmatchpre[last]=true
-              end
-              if replace then
-                while replace do
-                  if seq[n][getchar(replace)] then
-                    n=n+1
-                    replace=getnext(replace)
-                    if n>l then
-                      break
-                    end
-                  else
-                    notmatchreplace[last]=true
-                    match=not notmatchpre[last]
-                    break
-                  end
-                end
-                match=not notmatchpre[last]
-              end
-              last=getnext(last)
-            else
-              match=false
-              break
-            end
-          else
-            match=false
-            break
-          end
-        end
-      end
-      if match and f>1 then
-        local prev=getprev(start)
-        if prev then
-          if prev==checkdisc and (sweeptype=="pre" or sweeptype=="replace") then
-            prev=getprev(sweepnode)
-          end
-          if prev then
-            local discfound=nil
-            local n=f-1
-            while n>=1 do
-              if prev then
-                local char,id=ischar(prev,currentfont)
-                if char then
-                  local ccd=descriptions[char]
-                  if ccd then
-                    local class=ccd.class
-                    if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then
-                      skipped=true
-                      if trace_skips then
-                        show_skip(dataset,sequence,char,ck,class)
-                      end
-                      prev=getprev(prev) 
-                    elseif seq[n][char] then
-                      if n>1 then 
-                        prev=getprev(prev) 
-                      end
-                      n=n-1
-                    else
-                      if discfound then
-                        notmatchreplace[discfound]=true
-                        match=not notmatchpost[discfound]
-                      else
-                        match=false
-                      end
-                      break
-                    end
-                  else
-                    if discfound then
-                      notmatchreplace[discfound]=true
-                      match=not notmatchpost[discfound]
-                    else
-                      match=false
-                    end
-                    break
-                  end
-                elseif char==false then
-                  if discfound then
-                    notmatchreplace[discfound]=true
-                    match=not notmatchpost[discfound]
-                  else
-                    match=false
-                  end
-                  break
-                elseif id==disc_code then
-                  diskseen=true
-                  discfound=prev
-                  notmatchpre[prev]=true
-                  notmatchpost[prev]=nil
-                  notmatchreplace[prev]=nil
-                  local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true)
-                  if pre~=start and post~=start and replace~=start then
-                    if post then
-                      local n=n
-                      while posttail do
-                        if seq[n][getchar(posttail)] then
-                          n=n-1
-                          if posttail==post then
-                            break
-                          else
-                            posttail=getprev(posttail)
-                            if n<1 then
-                              break
-                            end
-                          end
-                        else
-                          notmatchpost[prev]=true
-                          break
-                        end
-                      end
-                      if n>=1 then
-                        notmatchpost[prev]=true
-                      end
-                    else
-                      notmatchpost[prev]=true
-                    end
-                    if replace then
-                      while replacetail do
-                        if seq[n][getchar(replacetail)] then
-                          n=n-1
-                          if replacetail==replace then
-                            break
-                          else
-                            replacetail=getprev(replacetail)
-                            if n<1 then
-                              break
-                            end
-                          end
-                        else
-                          notmatchreplace[prev]=true
-                          match=not notmatchpost[prev]
-                          break
-                        end
-                      end
-                      if not match then
-                        break
-                      end
-                    end
-                  end
-                  prev=getprev(prev)
-                elseif seq[n][32] and isspace(prev,threshold) then
-                  n=n-1
-                  prev=getprev(prev)
-                else
-                  match=false
-                  break
-                end
-              else
-                match=false
-                break
-              end
-            end
-          else
-            match=false
-          end
-        else
-          match=false
-        end
-      end
-      if match and s>l then
-        local current=last and getnext(last)
-        if not current then
-          if sweeptype=="post" or sweeptype=="replace" then
-            current=getnext(sweepnode)
-          end
-        end
-        if current then
-          local discfound=nil
-          local n=l+1
-          while n<=s do
-            if current then
-              local char,id=ischar(current,currentfont)
-              if char then
-                local ccd=descriptions[char]
-                if ccd then
-                  local class=ccd.class
-                  if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then
-                    skipped=true
-                    if trace_skips then
-                      show_skip(dataset,sequence,char,ck,class)
-                    end
-                    current=getnext(current) 
-                  elseif seq[n][char] then
-                    if n<s then 
-                      current=getnext(current) 
-                    end
-                    n=n+1
-                  else
-                    if discfound then
-                      notmatchreplace[discfound]=true
-                      match=not notmatchpre[discfound]
-                    else
-                      match=false
-                    end
-                    break
-                  end
-                else
-                  if discfound then
-                    notmatchreplace[discfound]=true
-                    match=not notmatchpre[discfound]
-                  else
-                    match=false
-                  end
-                  break
-                end
-              elseif char==false then
-                if discfound then
-                  notmatchreplace[discfound]=true
-                  match=not notmatchpre[discfound]
-                else
-                  match=false
-                end
-                break
-              elseif id==disc_code then
-                diskseen=true
-                discfound=current
-                notmatchpre[current]=nil
-                notmatchpost[current]=true
-                notmatchreplace[current]=nil
-                local pre,post,replace=getdisc(current)
-                if pre then
-                  local n=n
-                  while pre do
-                    if seq[n][getchar(pre)] then
-                      n=n+1
-                      pre=getnext(pre)
-                      if n>s then
-                        break
-                      end
-                    else
-                      notmatchpre[current]=true
-                      break
-                    end
-                  end
-                  if n<=s then
-                    notmatchpre[current]=true
-                  end
-                else
-                  notmatchpre[current]=true
-                end
-                if replace then
-                  while replace do
-                    if seq[n][getchar(replace)] then
-                      n=n+1
-                      replace=getnext(replace)
-                      if n>s then
-                        break
-                      end
-                    else
-                      notmatchreplace[current]=true
-                      match=notmatchpre[current]
-                      break
-                    end
-                  end
-                  if not match then
-                    break
-                  end
-                else
-                end
-                current=getnext(current)
-              elseif seq[n][32] and isspace(current,threshold) then
-                n=n+1
-                current=getnext(current)
-              else
-                match=false
-                break
-              end
-            else
-              match=false
-              break
-            end
-          end
-        else
-          match=false
-        end
-      end
-    end
-    if match then
-      local diskchain=diskseen or sweepnode
-      if trace_contexts then
-        local rule=ck[1]
-        local lookuptype=ck[8] or ck[2]
-        local first=ck[4]
-        local last=ck[5]
-        local char=getchar(start)
-        logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a",
-          cref(dataset,sequence),rule,gref(char),first-1,last-first+1,s-last,lookuptype)
-      end
-      local chainlookups=ck[6]
-      if chainlookups then
-        local nofchainlookups=#chainlookups
-        if size==1 then
-          local chainlookup=chainlookups[1]
-          local chainkind=chainlookup.type
-          local chainproc=chainprocs[chainkind]
-          if chainproc then
-            local ok
-            if diskchain then
-              head,start,ok=chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,1,ck,chainproc)
-            else
-              head,start,ok=chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,1)
-            end
-            if ok then
-              done=true
-            end
-          else
-            logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
-          end
-         else
-          local i=1
-          while start do
-            if skipped then
-              while start do 
-                local char=getchar(start)
-                local ccd=descriptions[char]
-                if ccd then
-                  local class=ccd.class or "base"
-                  if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then
-                    start=getnext(start)
-                  else
-                    break
-                  end
-                else
-                  break
-                end
-              end
-            end
-            local chainlookup=chainlookups[i]
-            if chainlookup then
-              local chainkind=chainlookup.type
-              local chainproc=chainprocs[chainkind]
-              if chainproc then
-                local ok,n
-                if diskchain then
-                  head,start,ok=chaindisk(head,start,last,dataset,sequence,chainlookup,rlmode,i,ck,chainproc)
-                else
-                  head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,i)
-                end
-                if ok then
-                  done=true
-                  if n and n>1 and i+n>nofchainlookups then
-                    break
-                  end
-                end
-              else
-                logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
-              end
-            end
-            i=i+1
-            if i>size or not start then
-              break
-            elseif start then
-              start=getnext(start)
-            end
-          end
-        end
-      else
-        local replacements=ck[7]
-        if replacements then
-          head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode)
-        else
-          done=true
-          if trace_contexts then
-            logprocess("%s: skipping match",cref(dataset,sequence))
-          end
-        end
-      end
-      if done then
-        break 
-      end
-    end
-  end
-  if diskseen then
-    notmatchpre={}
-    notmatchpost={}
-    notmatchreplace={}
-  end
-  return head,start,done
-end
-handlers.gsub_context=handle_contextchain
-handlers.gsub_contextchain=handle_contextchain
-handlers.gsub_reversecontextchain=handle_contextchain
-handlers.gpos_contextchain=handle_contextchain
-handlers.gpos_context=handle_contextchain
-local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode)
-  local steps=currentlookup.steps
-  local nofsteps=currentlookup.nofsteps
-  if nofsteps>1 then
-    reportmoresteps(dataset,sequence)
-  end
-  return handle_contextchain(head,start,dataset,sequence,currentlookup,rlmode)
-end
-chainprocs.gsub_context=chained_contextchain
-chainprocs.gsub_contextchain=chained_contextchain
-chainprocs.gsub_reversecontextchain=chained_contextchain
-chainprocs.gpos_contextchain=chained_contextchain
-chainprocs.gpos_context=chained_contextchain
-local missing=setmetatableindex("table")
-local function logprocess(...)
-  if trace_steps then
-    registermessage(...)
-  end
-  report_process(...)
-end
-local logwarning=report_process
-local function report_missing_coverage(dataset,sequence)
-  local t=missing[currentfont]
-  if not t[sequence] then
-    t[sequence]=true
-    logwarning("missing coverage for feature %a, lookup %a, type %a, font %a, name %a",
-      dataset[4],sequence.name,sequence.type,currentfont,tfmdata.properties.fullname)
-  end
-end
-local resolved={}
-local sequencelists=setmetatableindex(function(t,font)
-  local sequences=fontdata[font].resources.sequences
-  if not sequences or not next(sequences) then
-    sequences=false
-  end
-  t[font]=sequences
-  return sequences
-end)
-local autofeatures=fonts.analyzers.features
-local featuretypes=otf.tables.featuretypes
-local defaultscript=otf.features.checkeddefaultscript
-local defaultlanguage=otf.features.checkeddefaultlanguage
-local function initialize(sequence,script,language,enabled,autoscript,autolanguage)
-  local features=sequence.features
-  if features then
-    local order=sequence.order
-    if order then
-      local featuretype=featuretypes[sequence.type or "unknown"]
-      for i=1,#order do
-        local kind=order[i]
-        local valid=enabled[kind]
-        if valid then
-          local scripts=features[kind]
-          local languages=scripts and (
-            scripts[script] or
-            scripts[wildcard] or
-            (autoscript and defaultscript(featuretype,autoscript,scripts))
-          )
-          local enabled=languages and (
-            languages[language] or
-            languages[wildcard] or
-            (autolanguage and defaultlanguage(featuretype,autolanguage,languages))
-          )
-          if enabled then
-            return { valid,autofeatures[kind] or false,sequence,kind }
-          end
-        end
-      end
-    else
-    end
-  end
-  return false
-end
-function otf.dataset(tfmdata,font) 
-  local shared=tfmdata.shared
-  local properties=tfmdata.properties
-  local language=properties.language or "dflt"
-  local script=properties.script  or "dflt"
-  local enabled=shared.features
-  local autoscript=enabled and enabled.autoscript
-  local autolanguage=enabled and enabled.autolanguage
-  local res=resolved[font]
-  if not res then
-    res={}
-    resolved[font]=res
-  end
-  local rs=res[script]
-  if not rs then
-    rs={}
-    res[script]=rs
-  end
-  local rl=rs[language]
-  if not rl then
-    rl={
-    }
-    rs[language]=rl
-    local sequences=tfmdata.resources.sequences
-    if sequences then
-      for s=1,#sequences do
-        local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage)
-        if v then
-          rl[#rl+1]=v
-        end
-      end
-    end
-  end
-  return rl
-end
-local function report_disc(what,n)
-  report_run("%s: %s > %s",what,n,languages.serializediscretionary(n))
-end
-local function kernrun(disc,k_run,font,attr,...)
-  if trace_kernruns then
-    report_disc("kern",disc)
-  end
-  local prev,next=getboth(disc)
-  local nextstart=next
-  local done=false
-  local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
-  local prevmarks=prev
-  while prevmarks do
-    local char=ischar(prevmarks,font)
-    if char and marks[char] then
-      prevmarks=getprev(prevmarks)
-    else
-      break
-    end
-  end
-  if prev and not ischar(prev,font) then 
-    prev=false
-  end
-  if next and not ischar(next,font) then 
-    next=false
-  end
-  if pre then
-    if k_run(pre,"injections",nil,font,attr,...) then
-      done=true
-    end
-    if prev then
-      local nest=getprev(pre)
-      setlink(prev,pre)
-      if k_run(prevmarks,"preinjections",pre,font,attr,...) then 
-        done=true
-      end
-      setprev(pre,nest)
-      setnext(prev,disc)
-    end
-  end
-  if post then
-    if k_run(post,"injections",nil,font,attr,...) then
-      done=true
-    end
-    if next then
-      setlink(posttail,next)
-      if k_run(posttail,"postinjections",next,font,attr,...) then
-        done=true
-      end
-      setnext(posttail)
-      setprev(next,disc)
-    end
-  end
-  if replace then
-    if k_run(replace,"injections",nil,font,attr,...) then
-      done=true
-    end
-    if prev then
-      local nest=getprev(replace)
-      setlink(prev,replace)
-      if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then 
-        done=true
-      end
-      setprev(replace,nest)
-      setnext(prev,disc)
-    end
-    if next then
-      setlink(replacetail,next)
-      if k_run(replacetail,"replaceinjections",next,font,attr,...) then
-        done=true
-      end
-      setnext(replacetail)
-      setprev(next,disc)
-    end
-  elseif prev and next then
-    setlink(prev,next)
-    if k_run(prevmarks,"emptyinjections",next,font,attr,...) then
-      done=true
-    end
-    setlink(prev,disc)
-    setlink(disc,next)
-  end
-  return nextstart,done
-end
-local function comprun(disc,c_run,...)
-  if trace_compruns then
-    report_disc("comp",disc)
-  end
-  local pre,post,replace=getdisc(disc)
-  local renewed=false
-  if pre then
-    sweepnode=disc
-    sweeptype="pre" 
-    local new,done=c_run(pre,...)
-    if done then
-      pre=new
-      renewed=true
-    end
-  end
-  if post then
-    sweepnode=disc
-    sweeptype="post"
-    local new,done=c_run(post,...)
-    if done then
-      post=new
-      renewed=true
-    end
-  end
-  if replace then
-    sweepnode=disc
-    sweeptype="replace"
-    local new,done=c_run(replace,...)
-    if done then
-      replace=new
-      renewed=true
-    end
-  end
-  sweepnode=nil
-  sweeptype=nil
-  if renewed then
-    setdisc(disc,pre,post,replace)
-  end
-  return getnext(disc),renewed
-end
-local function testrun(disc,t_run,c_run,...)
-  if trace_testruns then
-    report_disc("test",disc)
-  end
-  local prev,next=getboth(disc)
-  if not next then
-    return
-  end
-  local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
-  local done=false
-  if replace and prev then
-    setlink(replacetail,next)
-    local ok,overflow=t_run(replace,next,...)
-    if ok and overflow then
-      setfield(disc,"replace")
-      setlink(prev,replace)
-      setboth(disc)
-      flush_node_list(disc)
-      return replace,true 
-    else
-      setnext(replacetail)
-      setprev(next,disc)
-    end
-  end
-  local renewed=false
-  if pre then
-    sweepnode=disc
-    sweeptype="pre"
-    local new,ok=c_run(pre,...)
-    if ok then
-      pre=new
-      renewed=true
-    end
-  end
-  if post then
-    sweepnode=disc
-    sweeptype="post"
-    local new,ok=c_run(post,...)
-    if ok then
-      post=new
-      renewed=true
-    end
-  end
-  if replace then
-    sweepnode=disc
-    sweeptype="replace"
-    local new,ok=c_run(replace,...)
-    if ok then
-      replace=new
-      renewed=true
-    end
-  end
-  sweepnode=nil
-  sweeptype=nil
-  if renewed then
-    setdisc(disc,pre,post,replace)
-    return next,true
-  else
-    return next,done
-  end
-end
-local nesting=0
-local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
-  local done=false
-  local sweep=sweephead[head]
-  if sweep then
-    start=sweep
-    sweephead[head]=nil
-  else
-    start=head
-  end
-  while start do
-    local char=ischar(start,font)
-    if char then
-      local a=attr and getattr(start,0)
-      if not a or (a==attr) then
-        local lookupmatch=lookupcache[char]
-        if lookupmatch then
-          local ok
-          head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,1)
-          if ok then
-            done=true
-          end
-        end
-        if start then
-          start=getnext(start)
-        end
-      else
-        start=getnext(start)
-      end
-    elseif char==false then
-      return head,done
-    elseif sweep then
-      return head,done
-    else
-      start=getnext(start)
-    end
-  end
-  return head,done
-end
-local function t_run_single(start,stop,font,attr,lookupcache)
-  while start~=stop do
-    local char=ischar(start,font)
-    if char then
-      local a=attr and getattr(start,0)
-      if not a or (a==attr) then
-        local lookupmatch=lookupcache[char]
-        if lookupmatch then
-          local s=getnext(start)
-          local l=nil
-          local d=0
-          while s do
-            if s==stop then
-              d=1
-            elseif d>0 then
-              d=d+1
-            end
-            local lg=lookupmatch[getchar(s)]
-            if lg then
-              l=lg
-              s=getnext(s)
-            else
-              break
-            end
-          end
-          if l and l.ligature then
-            return true,d>1
-          end
-        end
-      else
-      end
-      start=getnext(start)
-    else
-      break
-    end
-  end
-end
-local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
-  local a=attr and getattr(sub,0)
-  if not a or (a==attr) then
-    for n in traverse_nodes(sub) do 
-      if n==last then
-        break
-      end
-      local char=ischar(n)
-      if char then
-        local lookupmatch=lookupcache[char]
-        if lookupmatch then
-          local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,step,1,injection)
-          if ok then
-            return true
-          end
-        end
-      end
-    end
-  end
-end
-local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
-  local done=false
-  local sweep=sweephead[head]
-  if sweep then
-    start=sweep
-    sweephead[head]=nil
-  else
-    start=head
-  end
-  while start do
-    local char=ischar(start,font)
-    if char then
-      local a=attr and getattr(start,0)
-      if not a or (a==attr) then
-        for i=1,nofsteps do
-          local step=steps[i]
-          local lookupcache=step.coverage
-          if lookupcache then
-            local lookupmatch=lookupcache[char]
-            if lookupmatch then
-              local ok
-              head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
-              if ok then
-                done=true
-                break
-              elseif not start then
-                break
-              end
-            end
-          else
-            report_missing_coverage(dataset,sequence)
-          end
-        end
-        if start then
-          start=getnext(start)
-        end
-      else
-        start=getnext(start)
-      end
-    elseif char==false then
-      return head,done
-    elseif sweep then
-      return head,done
-    else
-      start=getnext(start)
-    end
-  end
-  return head,done
-end
-local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
-  while start~=stop do
-    local char=ischar(start,font)
-    if char then
-      local a=attr and getattr(start,0)
-      if not a or (a==attr) then
-        for i=1,nofsteps do
-          local step=steps[i]
-          local lookupcache=step.coverage
-          if lookupcache then
-            local lookupmatch=lookupcache[char]
-            if lookupmatch then
-              local s=getnext(start)
-              local l=nil
-              local d=0
-              while s do
-                if s==stop then
-                  d=1
-                elseif d>0 then
-                  d=d+1
-                end
-                local lg=lookupmatch[getchar(s)]
-                if lg then
-                  l=lg
-                  s=getnext(s)
-                else
-                  break
-                end
-              end
-              if l and l.ligature then
-                return true,d>1
-              end
-            end
-          else
-            report_missing_coverage(dataset,sequence)
-          end
-        end
-      else
-      end
-      start=getnext(start)
-    else
-      break
-    end
-  end
-end
-local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
-  local a=attr and getattr(sub,0)
-  if not a or (a==attr) then
-    for n in traverse_nodes(sub) do 
-      if n==last then
-        break
-      end
-      local char=ischar(n)
-      if char then
-        for i=1,nofsteps do
-          local step=steps[i]
-          local lookupcache=step.coverage
-          if lookupcache then
-            local lookupmatch=lookupcache[char]
-            if lookupmatch then
-              local h,d,ok=handler(head,n,dataset,sequence,lookupmatch,step,rlmode,i,injection)
-              if ok then
-                return true
-              end
-            end
-          else
-            report_missing_coverage(dataset,sequence)
-          end
-        end
-      end
-    end
-  end
-end
-local function txtdirstate(start,stack,top,rlparmode)
-  local dir=getfield(start,"dir")
-  local new=1
-  if dir=="+TRT" then
-    top=top+1
-    stack[top]=dir
-    new=-1
-  elseif dir=="+TLT" then
-    top=top+1
-    stack[top]=dir
-  elseif dir=="-TRT" or dir=="-TLT" then
-    top=top-1
-    if stack[top]=="+TRT" then
-      new=-1
-    end
-  else
-    new=rlparmode
-  end
-  if trace_directions then
-    report_process("directions after txtdir %a: parmode %a, txtmode %a, level %a",dir,mref(rlparmode),mref(new),top)
-  end
-  return getnext(start),top,new
-end
-local function pardirstate(start)
-  local dir=getfield(start,"dir")
-  local new=0
-  if dir=="TLT" then
-    new=1
-  elseif dir=="TRT" then
-    new=-1
-  end
-  if trace_directions then
-    report_process("directions after pardir %a: parmode %a",dir,mref(new))
-  end
-  return getnext(start),new,new
-end
-otf.helpers=otf.helpers or {}
-otf.helpers.txtdirstate=txtdirstate
-otf.helpers.pardirstate=pardirstate
-local function featuresprocessor(head,font,attr)
-  local sequences=sequencelists[font] 
-  if not sequencelists then
-    return head,false
-  end
-  nesting=nesting+1
-  if nesting==1 then
-    currentfont=font
-    tfmdata=fontdata[font]
-    descriptions=tfmdata.descriptions
-    characters=tfmdata.characters
-    marks=tfmdata.resources.marks
-    threshold,
-    factor=getthreshold(font)
-    checkmarks=tfmdata.properties.checkmarks
-  elseif currentfont~=font then
-    report_warning("nested call with a different font, level %s, quitting",nesting)
-    nesting=nesting-1
-    return head,false
-  end
-  head=tonut(head)
-  if trace_steps then
-    checkstep(head)
-  end
-  local rlmode=0
-  local done=false
-  local datasets=otf.dataset(tfmdata,font,attr)
-  local forcedisc=alwaysdisc or not attr
-  local dirstack={} 
-  sweephead={}
-  for s=1,#datasets do
-    local dataset=datasets[s]
-    local attribute=dataset[2]
-    local sequence=dataset[3] 
-    local rlparmode=0
-    local topstack=0
-    local success=false
-    local typ=sequence.type
-    local gpossing=typ=="gpos_single" or typ=="gpos_pair" 
-    local handler=handlers[typ]
-    local steps=sequence.steps
-    local nofsteps=sequence.nofsteps
-    if not steps then
-      local h,d,ok=handler(head,head,dataset,sequence,nil,nil,nil,0,font,attr)
-      if ok then
-        success=true
-        if h then
-          head=h
-        end
-      end
-    elseif typ=="gsub_reversecontextchain" then
-      local start=find_node_tail(head)
-      while start do
-        local char=ischar(start,font)
-        if char then
-          local a=attr and getattr(start,0)
-          if not a or (a==attr) then
-            for i=1,nofsteps do
-              local step=steps[i]
-              local lookupcache=step.coverage
-              if lookupcache then
-                local lookupmatch=lookupcache[char]
-                if lookupmatch then
-                  local ok
-                  head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
-                  if ok then
-                    success=true
-                    break
-                  end
-                end
-              else
-                report_missing_coverage(dataset,sequence)
-              end
-            end
-            if start then
-              start=getprev(start)
-            end
-          else
-            start=getprev(start)
-          end
-        else
-          start=getprev(start)
-        end
-      end
-    else
-      local start=head 
-      rlmode=0 
-      if nofsteps==1 then 
-        local step=steps[1]
-        local lookupcache=step.coverage
-        if not lookupcache then
-          report_missing_coverage(dataset,sequence)
-        else
-          while start do
-            local char,id=ischar(start,font)
-            if char then
-              local a=attr and getattr(start,0)
-              if a then
-                a=(a==attr) and (not attribute or getprop(start,a_state)==attribute)
-              else
-                a=not attribute or getprop(start,a_state)==attribute
-              end
-              if a then
-                local lookupmatch=lookupcache[char]
-                if lookupmatch then
-                  local ok
-                  head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,1)
-                  if ok then
-                    success=true
-                  end
-                end
-                if start then
-                  start=getnext(start)
-                end
-              else
-                start=getnext(start)
-              end
-            elseif char==false then
-              start=getnext(start)
-            elseif id==disc_code then
-              local a=forcedisc or getsubtype(start)==discretionary_code or getattr(start,0)==attr
-              if a then
-                local ok
-                if gpossing then
-                  start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
-                elseif typ=="gsub_ligature" then
-                  start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
-                else
-                  start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,handler)
-                end
-                if ok then
-                  success=true
-                end
-              else
-                start=getnext(start)
-              end
-            elseif id==math_code then
-              start=getnext(end_of_math(start))
-            elseif id==dir_code then
-              start,topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
-            elseif id==localpar_code then
-              start,rlparmode,rlmode=pardirstate(start)
-            else
-              start=getnext(start)
-            end
-          end
-        end
-      else
-        while start do
-          local char,id=ischar(start,font)
-          if char then
-            local a=attr and getattr(start,0)
-            if a then
-              a=(a==attr) and (not attribute or getprop(start,a_state)==attribute)
-            else
-              a=not attribute or getprop(start,a_state)==attribute
-            end
-            if a then
-              for i=1,nofsteps do
-                local step=steps[i]
-                local lookupcache=step.coverage
-                if lookupcache then
-                  local lookupmatch=lookupcache[char]
-                  if lookupmatch then
-                    local ok
-                    head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,step,i)
-                    if ok then
-                      success=true
-                      break
-                    elseif not start then
-                      break
-                    end
-                  end
-                else
-                  report_missing_coverage(dataset,sequence)
-                end
-              end
-              if start then
-                start=getnext(start)
-              end
-            else
-              start=getnext(start)
-            end
-          elseif char==false then
-            start=getnext(start)
-          elseif id==disc_code then
-            local a=forcedisc or getsubtype(start)==discretionary_code or getattr(start,0)==attr
-            if a then
-              local ok
-              if gpossing then
-                start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
-              elseif typ=="gsub_ligature" then
-                start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
-              else
-                start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler)
-              end
-              if ok then
-                success=true
-              end
-            else
-              start=getnext(start)
-            end
-          elseif id==math_code then
-            start=getnext(end_of_math(start))
-          elseif id==dir_code then
-            start,topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
-          elseif id==localpar_code then
-            start,rlparmode,rlmode=pardirstate(start)
-          else
-            start=getnext(start)
-          end
-        end
-      end
-    end
-    if success then
-      done=true
-    end
-    if trace_steps then 
-      registerstep(head)
-    end
-  end
-  nesting=nesting-1
-  head=tonode(head)
-  return head,done
-end
-local plugins={}
-otf.plugins=plugins
-function otf.registerplugin(name,f)
-  if type(name)=="string" and type(f)=="function" then
-    plugins[name]={ name,f }
-  end
-end
-local function plugininitializer(tfmdata,value)
-  if type(value)=="string" then
-    tfmdata.shared.plugin=plugins[value]
-  end
-end
-local function pluginprocessor(head,font)
-  local s=fontdata[font].shared
-  local p=s and s.plugin
-  if p then
-    if trace_plugins then
-      report_process("applying plugin %a",p[1])
-    end
-    return p[2](head,font)
-  else
-    return head,false
-  end
-end
-local function featuresinitializer(tfmdata,value)
-end
-registerotffeature {
-  name="features",
-  description="features",
-  default=true,
-  initializers={
-    position=1,
-    node=featuresinitializer,
-    plug=plugininitializer,
-  },
-  processors={
-    node=featuresprocessor,
-    plug=pluginprocessor,
-  }
-}
-otf.nodemodeinitializer=featuresinitializer
-otf.featuresprocessor=featuresprocessor
-otf.handlers=handlers
-local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end
-if fontfeatures then
-  function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr)
-    local features=fontfeatures[font]
-    local enabled=features and features.spacekern and features.kern
-    if enabled then
-      setspacekerns(font,sequence)
-    end
-    return head,start,enabled
-  end
-else 
-  function otf.handlers.trigger_space_kerns(head,start,dataset,sequence,_,_,_,_,font,attr)
-    local shared=fontdata[font].shared
-    local features=shared and shared.features
-    local enabled=features and features.spacekern and features.kern
-    if enabled then
-      setspacekerns(font,sequence)
-    end
-    return head,start,enabled
-  end
-end
-local function hasspacekerns(data)
-  local sequences=data.resources.sequences
-  for i=1,#sequences do
-    local sequence=sequences[i]
-    local steps=sequence.steps
-    if steps and sequence.features.kern then
-      for i=1,#steps do
-        local coverage=steps[i].coverage
-        if not coverage then
-        elseif coverage[32] then
-          return true
-        else
-          for k,v in next,coverage do
-            if v[32] then
-              return true
-            end
-          end
-        end
-      end
-    end
-  end
-  return false
-end
-otf.readers.registerextender {
-  name="spacekerns",
-  action=function(data)
-    data.properties.hasspacekerns=hasspacekerns(data)
-  end
-}
-local function spaceinitializer(tfmdata,value) 
-  local resources=tfmdata.resources
-  local spacekerns=resources and resources.spacekerns
-  local properties=tfmdata.properties
-  if value and spacekerns==nil then
-    if properties and properties.hasspacekerns then
-      local sequences=resources.sequences
-      local left={}
-      local right={}
-      local last=0
-      local feat=nil
-      for i=1,#sequences do
-        local sequence=sequences[i]
-        local steps=sequence.steps
-        if steps then
-          local kern=sequence.features.kern
-          if kern then
-            if feat then
-              for script,languages in next,kern do
-                local f=feat[script]
-                if f then
-                  for l in next,languages do
-                    f[l]=true
-                  end
-                else
-                  feat[script]=languages
-                end
-              end
-            else
-              feat=kern
-            end
-            for i=1,#steps do
-              local step=steps[i]
-              local coverage=step.coverage
-              local rules=step.rules
-              local format=step.format
-              if rules then
-              elseif coverage then
-                local single=format==gpos_single
-                local kerns=coverage[32]
-                if kerns then
-                  for k,v in next,kerns do
-                    if type(v)~="table" then
-                      right[k]=v
-                    elseif single then
-                      right[k]=v[3]
-                    else
-                      local one=v[1]
-                      if one then
-                        right[k]=one[3]
-                      end
-                    end
-                  end
-                end
-                for k,v in next,coverage do
-                  local kern=v[32]
-                  if kern then
-                    if type(kern)~="table" then
-                      left[k]=kern
-                    elseif single then
-                      left[k]=v[3]
-                    else
-                      local one=v[1]
-                      if one then
-                        left[k]=one[3]
-                      end
-                    end
-                  end
-                end
-              end
-            end
-            last=i
-          end
-        else
-        end
-      end
-      left=next(left) and left or false
-      right=next(right) and right or false
-      if left or right then
-        spacekerns={
-          left=left,
-          right=right,
-        }
-        if last>0 then
-          local triggersequence={
-            features={ kern=feat or { dflt={ dflt=true,} } },
-            flags=noflags,
-            name="trigger_space_kerns",
-            order={ "kern" },
-            type="trigger_space_kerns",
-            left=left,
-            right=right,
-          }
-          insert(sequences,last,triggersequence)
-        end
-      else
-        spacekerns=false
-      end
-    else
-      spacekerns=false
-    end
-    resources.spacekerns=spacekerns
-  end
-  return spacekerns
-end
-registerotffeature {
-  name="spacekern",
-  description="space kern injection",
-  default=true,
-  initializers={
-    node=spaceinitializer,
-  },
-}
-local function markinitializer(tfmdata,value)
-  local properties=tfmdata.properties
-  properties.checkmarks=value
-end
-registerotffeature {
-  name="checkmarks",
-  description="check mark widths",
-  default=true,
-  initializers={
-    node=markinitializer,
-  },
-}
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-ots”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-osd” 10ecd4b375680b011e7c6a25e5ad74f7] ---
-
-if not modules then modules={} end modules ['font-osd']={ 
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE",
-  copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local insert,imerge,copy=table.insert,table.imerge,table.copy
-local next,type=next,type
-local report_devanagari=logs.reporter("otf","devanagari")
-fonts=fonts          or {}
-fonts.analyzers=fonts.analyzers     or {}
-fonts.analyzers.methods=fonts.analyzers.methods or { node={ otf={} } }
-local otf=fonts.handlers.otf
-local handlers=otf.handlers
-local methods=fonts.analyzers.methods
-local otffeatures=fonts.constructors.features.otf
-local registerotffeature=otffeatures.register
-local nuts=nodes.nuts
-local tonode=nuts.tonode
-local tonut=nuts.tonut
-local getnext=nuts.getnext
-local getprev=nuts.getprev
-local getboth=nuts.getboth
-local getid=nuts.getid
-local getchar=nuts.getchar
-local getfont=nuts.getfont
-local getsubtype=nuts.getsubtype
-local setlink=nuts.setlink
-local setnext=nuts.setnext
-local setprev=nuts.setprev
-local setchar=nuts.setchar
-local getprop=nuts.getprop
-local setprop=nuts.setprop
-local ischar=nuts.is_char
-local insert_node_after=nuts.insert_after
-local copy_node=nuts.copy
-local remove_node=nuts.remove
-local flush_list=nuts.flush_list
-local flush_node=nuts.flush_node
-local copyinjection=nodes.injections.copy 
-local unsetvalue=attributes.unsetvalue
-local fontdata=fonts.hashes.identifiers
-local a_state=attributes.private('state')
-local a_syllabe=attributes.private('syllabe')
-local dotted_circle=0x25CC
-local states=fonts.analyzers.states 
-local s_rphf=states.rphf
-local s_half=states.half
-local s_pref=states.pref
-local s_blwf=states.blwf
-local s_pstf=states.pstf
-local replace_all_nbsp=nil
-replace_all_nbsp=function(head) 
-  replace_all_nbsp=typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head)
-    return head
-  end
-  return replace_all_nbsp(head)
-end
-local xprocesscharacters=nil
-if context then
-  xprocesscharacters=function(head,font)
-    xprocesscharacters=nodes.handlers.characters
-    return xprocesscharacters(head,font)
-  end
-else
-  xprocesscharacters=function(head,font)
-    xprocesscharacters=nodes.handlers.nodepass 
-    return xprocesscharacters(head,font)
-  end
-end
-local function processcharacters(head,font)
-  return tonut(xprocesscharacters(tonode(head))) 
-end
-local consonant={
-  [0x0915]=true,[0x0916]=true,[0x0917]=true,[0x0918]=true,
-  [0x0919]=true,[0x091A]=true,[0x091B]=true,[0x091C]=true,
-  [0x091D]=true,[0x091E]=true,[0x091F]=true,[0x0920]=true,
-  [0x0921]=true,[0x0922]=true,[0x0923]=true,[0x0924]=true,
-  [0x0925]=true,[0x0926]=true,[0x0927]=true,[0x0928]=true,
-  [0x0929]=true,[0x092A]=true,[0x092B]=true,[0x092C]=true,
-  [0x092D]=true,[0x092E]=true,[0x092F]=true,[0x0930]=true,
-  [0x0931]=true,[0x0932]=true,[0x0933]=true,[0x0934]=true,
-  [0x0935]=true,[0x0936]=true,[0x0937]=true,[0x0938]=true,
-  [0x0939]=true,[0x0958]=true,[0x0959]=true,[0x095A]=true,
-  [0x095B]=true,[0x095C]=true,[0x095D]=true,[0x095E]=true,
-  [0x095F]=true,[0x0979]=true,[0x097A]=true,
-  [0x0C95]=true,[0x0C96]=true,[0x0C97]=true,[0x0C98]=true,
-  [0x0C99]=true,[0x0C9A]=true,[0x0C9B]=true,[0x0C9C]=true,
-  [0x0C9D]=true,[0x0C9E]=true,[0x0C9F]=true,[0x0CA0]=true,
-  [0x0CA1]=true,[0x0CA2]=true,[0x0CA3]=true,[0x0CA4]=true,
-  [0x0CA5]=true,[0x0CA6]=true,[0x0CA7]=true,[0x0CA8]=true,
-  [0x0CA9]=true,[0x0CAA]=true,[0x0CAB]=true,[0x0CAC]=true,
-  [0x0CAD]=true,[0x0CAE]=true,[0x0CAF]=true,[0x0CB0]=true,
-  [0x0CB1]=true,[0x0CB2]=true,[0x0CB3]=true,[0x0CB4]=true,
-  [0x0CB5]=true,[0x0CB6]=true,[0x0CB7]=true,[0x0CB8]=true,
-  [0x0CB9]=true,
-  [0x0CDE]=true,
-  [0x0D15]=true,[0x0D16]=true,[0x0D17]=true,[0x0D18]=true,
-  [0x0D19]=true,[0x0D1A]=true,[0x0D1B]=true,[0x0D1C]=true,
-  [0x0D1D]=true,[0x0D1E]=true,[0x0D1F]=true,[0x0D20]=true,
-  [0x0D21]=true,[0x0D22]=true,[0x0D23]=true,[0x0D24]=true,
-  [0x0D25]=true,[0x0D26]=true,[0x0D27]=true,[0x0D28]=true,
-  [0x0D29]=true,[0x0D2A]=true,[0x0D2B]=true,[0x0D2C]=true,
-  [0x0D2D]=true,[0x0D2E]=true,[0x0D2F]=true,[0x0D30]=true,
-  [0x0D31]=true,[0x0D32]=true,[0x0D33]=true,[0x0D34]=true,
-  [0x0D35]=true,[0x0D36]=true,[0x0D37]=true,[0x0D38]=true,
-  [0x0D39]=true,[0x0D3A]=true,
-}
-local independent_vowel={
-  [0x0904]=true,[0x0905]=true,[0x0906]=true,[0x0907]=true,
-  [0x0908]=true,[0x0909]=true,[0x090A]=true,[0x090B]=true,
-  [0x090C]=true,[0x090D]=true,[0x090E]=true,[0x090F]=true,
-  [0x0910]=true,[0x0911]=true,[0x0912]=true,[0x0913]=true,
-  [0x0914]=true,[0x0960]=true,[0x0961]=true,[0x0972]=true,
-  [0x0973]=true,[0x0974]=true,[0x0975]=true,[0x0976]=true,
-  [0x0977]=true,
-  [0x0C85]=true,[0x0C86]=true,[0x0C87]=true,[0x0C88]=true,
-  [0x0C89]=true,[0x0C8A]=true,[0x0C8B]=true,[0x0C8C]=true,
-  [0x0C8D]=true,[0x0C8E]=true,[0x0C8F]=true,[0x0C90]=true,
-  [0x0C91]=true,[0x0C92]=true,[0x0C93]=true,[0x0C94]=true,
-  [0x0D05]=true,[0x0D06]=true,[0x0D07]=true,[0x0D08]=true,
-  [0x0D09]=true,[0x0D0A]=true,[0x0D0B]=true,[0x0D0C]=true,
-  [0x0D0E]=true,[0x0D0F]=true,[0x0D10]=true,[0x0D12]=true,
-  [0x0D13]=true,[0x0D14]=true,
-}
-local dependent_vowel={
-  [0x093A]=true,[0x093B]=true,[0x093E]=true,[0x093F]=true,
-  [0x0940]=true,[0x0941]=true,[0x0942]=true,[0x0943]=true,
-  [0x0944]=true,[0x0945]=true,[0x0946]=true,[0x0947]=true,
-  [0x0948]=true,[0x0949]=true,[0x094A]=true,[0x094B]=true,
-  [0x094C]=true,[0x094E]=true,[0x094F]=true,[0x0955]=true,
-  [0x0956]=true,[0x0957]=true,[0x0962]=true,[0x0963]=true,
-  [0x0CBE]=true,[0x0CBF]=true,[0x0CC0]=true,[0x0CC1]=true,
-  [0x0CC2]=true,[0x0CC3]=true,[0x0CC4]=true,[0x0CC5]=true,
-  [0x0CC6]=true,[0x0CC7]=true,[0x0CC8]=true,[0x0CC9]=true,
-  [0x0CCA]=true,[0x0CCB]=true,[0x0CCC]=true,
-  [0x0D3E]=true,[0x0D3F]=true,[0x0D40]=true,[0x0D41]=true,
-  [0x0D42]=true,[0x0D43]=true,[0x0D44]=true,[0x0D46]=true,
-  [0x0D47]=true,[0x0D48]=true,[0x0D4A]=true,[0x0D4B]=true,
-  [0x0D4C]=true,[0x0D57]=true,
-}
-local vowel_modifier={
-  [0x0900]=true,[0x0901]=true,[0x0902]=true,[0x0903]=true,
-  [0xA8E0]=true,[0xA8E1]=true,[0xA8E2]=true,[0xA8E3]=true,
-  [0xA8E4]=true,[0xA8E5]=true,[0xA8E6]=true,[0xA8E7]=true,
-  [0xA8E8]=true,[0xA8E9]=true,[0xA8EA]=true,[0xA8EB]=true,
-  [0xA8EC]=true,[0xA8ED]=true,[0xA8EE]=true,[0xA8EF]=true,
-  [0xA8F0]=true,[0xA8F1]=true,
-  [0x0D02]=true,[0x0D03]=true,
-}
-local stress_tone_mark={
-  [0x0951]=true,[0x0952]=true,[0x0953]=true,[0x0954]=true,
-  [0x0CCD]=true,
-  [0x0D4D]=true,
-}
-local nukta={
-  [0x093C]=true,
-  [0x0CBC]=true,
-}
-local halant={
-  [0x094D]=true,
-  [0x0CCD]=true,
-  [0x0D4D]=true,
-}
-local ra={
-  [0x0930]=true,
-  [0x0CB0]=true,
-  [0x0D30]=true,
-}
-local c_anudatta=0x0952 
-local c_nbsp=0x00A0 
-local c_zwnj=0x200C 
-local c_zwj=0x200D 
-local zw_char={ 
-  [0x200C]=true,
-  [0x200D]=true,
-}
-local pre_mark={
-  [0x093F]=true,[0x094E]=true,
-  [0x0D46]=true,[0x0D47]=true,[0x0D48]=true,
-}
-local above_mark={
-  [0x0900]=true,[0x0901]=true,[0x0902]=true,[0x093A]=true,
-  [0x0945]=true,[0x0946]=true,[0x0947]=true,[0x0948]=true,
-  [0x0951]=true,[0x0953]=true,[0x0954]=true,[0x0955]=true,
-  [0xA8E0]=true,[0xA8E1]=true,[0xA8E2]=true,[0xA8E3]=true,
-  [0xA8E4]=true,[0xA8E5]=true,[0xA8E6]=true,[0xA8E7]=true,
-  [0xA8E8]=true,[0xA8E9]=true,[0xA8EA]=true,[0xA8EB]=true,
-  [0xA8EC]=true,[0xA8ED]=true,[0xA8EE]=true,[0xA8EF]=true,
-  [0xA8F0]=true,[0xA8F1]=true,
-  [0x0D4E]=true,
-}
-local below_mark={
-  [0x093C]=true,[0x0941]=true,[0x0942]=true,[0x0943]=true,
-  [0x0944]=true,[0x094D]=true,[0x0952]=true,[0x0956]=true,
-  [0x0957]=true,[0x0962]=true,[0x0963]=true,
-}
-local post_mark={
-  [0x0903]=true,[0x093B]=true,[0x093E]=true,[0x0940]=true,
-  [0x0949]=true,[0x094A]=true,[0x094B]=true,[0x094C]=true,
-  [0x094F]=true,
-}
-local twopart_mark={
-  [0x0D4A]={ 0x0D46,0x0D3E,},	
-  [0x0D4B]={ 0x0D47,0x0D3E,},	
-  [0x0D4C]={ 0x0D46,0x0D57,},	
-}
-local mark_four={} 
-for k,v in next,pre_mark  do mark_four[k]=pre_mark  end
-for k,v in next,above_mark do mark_four[k]=above_mark end
-for k,v in next,below_mark do mark_four[k]=below_mark end
-for k,v in next,post_mark do mark_four[k]=post_mark end
-local mark_above_below_post={}
-for k,v in next,above_mark do mark_above_below_post[k]=above_mark end
-for k,v in next,below_mark do mark_above_below_post[k]=below_mark end
-for k,v in next,post_mark do mark_above_below_post[k]=post_mark end
-local reorder_class={
-  [0x0930]="before postscript",
-  [0x093F]="before half",
-  [0x0940]="after subscript",
-  [0x0941]="after subscript",
-  [0x0942]="after subscript",
-  [0x0943]="after subscript",
-  [0x0944]="after subscript",
-  [0x0945]="after subscript",
-  [0x0946]="after subscript",
-  [0x0947]="after subscript",
-  [0x0948]="after subscript",
-  [0x0949]="after subscript",
-  [0x094A]="after subscript",
-  [0x094B]="after subscript",
-  [0x094C]="after subscript",
-  [0x0962]="after subscript",
-  [0x0963]="after subscript",
-  [0x093E]="after subscript",
-  [0x0CB0]="after postscript",
-  [0x0CBF]="before subscript",
-  [0x0CC6]="before subscript",
-  [0x0CCC]="before subscript",
-  [0x0CBE]="before subscript",
-  [0x0CE2]="before subscript",
-  [0x0CE3]="before subscript",
-  [0x0CC1]="before subscript",
-  [0x0CC2]="before subscript",
-  [0x0CC3]="after subscript",
-  [0x0CC4]="after subscript",
-  [0x0CD5]="after subscript",
-  [0x0CD6]="after subscript",
-}
-local dflt_true={
-  dflt=true
-}
-local dev2_defaults={
-  dev2=dflt_true,
-}
-local deva_defaults={
-  dev2=dflt_true,
-  deva=dflt_true,
-}
-local false_flags={ false,false,false,false }
-local both_joiners_true={
-  [0x200C]=true,
-  [0x200D]=true,
-}
-local sequence_reorder_matras={
-  features={ dv01=dev2_defaults },
-  flags=false_flags,
-  name="dv01_reorder_matras",
-  order={ "dv01" },
-  type="devanagari_reorder_matras",
-  nofsteps=1,
-  steps={
-    {
-      osdstep=true,
-      coverage=pre_mark,
-    }
-  }
-}
-local sequence_reorder_reph={
-  features={ dv02=dev2_defaults },
-  flags=false_flags,
-  name="dv02_reorder_reph",
-  order={ "dv02" },
-  type="devanagari_reorder_reph",
-  nofsteps=1,
-  steps={
-    {
-      osdstep=true,
-      coverage={},
-    }
-  }
-}
-local sequence_reorder_pre_base_reordering_consonants={
-  features={ dv03=dev2_defaults },
-  flags=false_flags,
-  name="dv03_reorder_pre_base_reordering_consonants",
-  order={ "dv03" },
-  type="devanagari_reorder_pre_base_reordering_consonants",
-  nofsteps=1,
-  steps={
-    {
-      osdstep=true,
-      coverage={},
-    }
-  }
-}
-local sequence_remove_joiners={
-  features={ dv04=deva_defaults },
-  flags=false_flags,
-  name="dv04_remove_joiners",
-  order={ "dv04" },
-  type="devanagari_remove_joiners",
-  nofsteps=1,
-  steps={
-    { osdstep=true,
-      coverage=both_joiners_true,
-    },
-  }
-}
-local basic_shaping_forms={
-  nukt=true,
-  akhn=true,
-  rphf=true,
-  pref=true,
-  rkrf=true,
-  blwf=true,
-  half=true,
-  pstf=true,
-  vatu=true,
-  cjct=true,
-}
-local valid={
-  akhn=true,
-  rphf=true,
-  pref=true,
-  half=true,
-  blwf=true,
-  pstf=true,
-  pres=true,
-  blws=true,
-  psts=true,
-}
-local function initializedevanagi(tfmdata)
-  local script,language=otf.scriptandlanguage(tfmdata,attr) 
-  if script=="deva" or script=="dev2" or script=="mlym" or script=="mlm2" then
-    local resources=tfmdata.resources
-    local devanagari=resources.devanagari
-    if not devanagari then
-      report_devanagari("adding devanagari features to font")
-      local gsubfeatures=resources.features.gsub
-      local sequences=resources.sequences
-      local sharedfeatures=tfmdata.shared.features
-      local lastmatch=0
-      for s=1,#sequences do 
-        local features=sequences[s].features
-        if features then
-          for k,v in next,features do
-            if basic_shaping_forms[k] then
-              lastmatch=s
-            end
-          end
-        end
-      end
-      local insertindex=lastmatch+1
-      gsubfeatures["dv01"]=dev2_defaults 
-      gsubfeatures["dv02"]=dev2_defaults 
-      gsubfeatures["dv03"]=dev2_defaults 
-      gsubfeatures["dv04"]=deva_defaults
-      local reorder_pre_base_reordering_consonants=copy(sequence_reorder_pre_base_reordering_consonants)
-      local reorder_reph=copy(sequence_reorder_reph)
-      local reorder_matras=copy(sequence_reorder_matras)
-      local remove_joiners=copy(sequence_remove_joiners)
-      insert(sequences,insertindex,reorder_pre_base_reordering_consonants)
-      insert(sequences,insertindex,reorder_reph)
-      insert(sequences,insertindex,reorder_matras)
-      insert(sequences,insertindex,remove_joiners)
-      local blwfcache={}
-      local seqsubset={}
-      local rephstep={
-        coverage={} 
-      }
-      local devanagari={
-        reph=false,
-        vattu=false,
-        blwfcache=blwfcache,
-        seqsubset=seqsubset,
-        reorderreph=rephstep,
-      }
-      reorder_reph.steps={ rephstep }
-      local pre_base_reordering_consonants={}
-      reorder_pre_base_reordering_consonants.steps[1].coverage=pre_base_reordering_consonants
-      resources.devanagari=devanagari
-      for s=1,#sequences do
-        local sequence=sequences[s]
-        local steps=sequence.steps
-        local nofsteps=sequence.nofsteps
-        local features=sequence.features
-        local has_rphf=features.rphf
-        local has_blwf=features.blwf
-        if has_rphf and has_rphf.deva then
-          devanagari.reph=true
-        elseif has_blwf and has_blwf.deva then
-          devanagari.vattu=true
-          for i=1,nofsteps do
-            local step=steps[i]
-            local coverage=step.coverage
-            if coverage then
-              for k,v in next,coverage do
-                if not blwfcache[k] then
-                  blwfcache[k]=v
-                end
-              end
-            end
-          end
-        end
-        for kind,spec in next,features do 
-          if spec.dev2 and valid[kind] then
-            for i=1,nofsteps do
-              local step=steps[i]
-              local coverage=step.coverage
-              if coverage then
-                local reph=false
-                if kind=="rphf" then
-                  if true then
-                    for k,v in next,ra do
-                      local r=coverage[k]
-                      if r then
-                        local h=false
-                        for k,v in next,halant do
-                          local h=r[k]
-                          if h then
-                            reph=h.ligature or false
-                            break
-                          end
-                        end
-                        if reph then
-                          break
-                        end
-                      end
-                    end
-                  else
-                  end
-                end
-                seqsubset[#seqsubset+1]={ kind,coverage,reph }
-              end
-            end
-          end
-          if kind=="pref" then
-            local steps=sequence.steps
-            local nofsteps=sequence.nofsteps
-            for i=1,nofsteps do
-              local step=steps[i]
-              local coverage=step.coverage
-              if coverage then
-                for k,v in next,halant do
-                  local h=coverage[k]
-                  if h then
-                    local found=false
-                    for k,v in next,h do
-                      found=v and v.ligature
-                      if found then
-                        pre_base_reordering_consonants[k]=found
-                        break
-                      end
-                    end
-                    if found then
-                      break
-                    end
-                  end
-                end
-              end
-            end
-          end
-        end
-      end
-      if script=="deva" then
-        sharedfeatures["dv04"]=true 
-      elseif script=="dev2" then
-        sharedfeatures["dv01"]=true 
-        sharedfeatures["dv02"]=true 
-        sharedfeatures["dv03"]=true 
-        sharedfeatures["dv04"]=true 
-      elseif script=="mlym" then
-        sharedfeatures["pstf"]=true
-      elseif script=="mlm2" then
-        sharedfeatures["pstf"]=true
-        sharedfeatures["pref"]=true
-        sharedfeatures["dv03"]=true 
-        gsubfeatures ["dv03"]=dev2_defaults 
-        insert(sequences,insertindex,sequence_reorder_pre_base_reordering_consonants)
-      end
-    end
-  end
-end
-registerotffeature {
-  name="devanagari",
-  description="inject additional features",
-  default=true,
-  initializers={
-    node=initializedevanagi,
-  },
-}
-local function deva_initialize(font,attr) 
-  local tfmdata=fontdata[font]
-  local datasets=otf.dataset(tfmdata,font,attr) 
-  local devanagaridata=datasets.devanagari
-  if not devanagaridata then
-    devanagaridata={
-      reph=false,
-      vattu=false,
-      blwfcache={},
-    }
-    datasets.devanagari=devanagaridata
-    local resources=tfmdata.resources
-    local devanagari=resources.devanagari
-    for s=1,#datasets do
-      local dataset=datasets[s]
-      if dataset and dataset[1] then 
-        local kind=dataset[4]
-        if kind=="rphf" then
-          devanagaridata.reph=true
-        elseif kind=="blwf" then
-          devanagaridata.vattu=true
-          devanagaridata.blwfcache=devanagari.blwfcache
-        end
-      end
-    end
-  end
-  return devanagaridata.reph,devanagaridata.vattu,devanagaridata.blwfcache
-end
-local function deva_reorder(head,start,stop,font,attr,nbspaces)
-  local reph,vattu,blwfcache=deva_initialize(font,attr) 
-  local current=start
-  local n=getnext(start)
-  local base=nil
-  local firstcons=nil
-  local lastcons=nil
-  local basefound=false
-  if reph and ra[getchar(start)] and halant[getchar(n)] then
-    if n==stop then
-      return head,stop,nbspaces
-    end
-    if getchar(getnext(n))==c_zwj then
-      current=start
-    else
-      current=getnext(n)
-      setprop(start,a_state,s_rphf)
-    end
-  end
-  if getchar(current)==c_nbsp then
-    if current==stop then
-      stop=getprev(stop)
-      head=remove_node(head,current)
-      flush_node(current)
-      return head,stop,nbspaces
-    else
-      nbspaces=nbspaces+1
-      base=current
-      firstcons=current
-      lastcons=current
-      current=getnext(current)
-      if current~=stop then
-        if nukta[getchar(current)] then
-          current=getnext(current)
-        end
-        if getchar(current)==c_zwj then
-          if current~=stop then
-            local next=getnext(current)
-            if next~=stop and halant[getchar(next)] then
-              current=next
-              next=getnext(current)
-              local tmp=next and getnext(next) or nil 
-              local changestop=next==stop
-              local tempcurrent=copy_node(next)
-							copyinjection(tempcurrent,next)
-              local nextcurrent=copy_node(current)
-							copyinjection(nextcurrent,current) 
-              setlink(tempcurrent,nextcurrent)
-              setprop(tempcurrent,a_state,s_blwf)
-              tempcurrent=processcharacters(tempcurrent,font)
-              setprop(tempcurrent,a_state,unsetvalue)
-              if getchar(next)==getchar(tempcurrent) then
-                flush_list(tempcurrent)
-                local n=copy_node(current)
-								copyinjection(n,current) 
-                setchar(current,dotted_circle)
-                head=insert_node_after(head,current,n)
-              else
-                setchar(current,getchar(tempcurrent)) 
-                local freenode=getnext(current)
-                setlink(current,tmp)
-                flush_node(freenode)
-                flush_list(tempcurrent)
-                if changestop then
-                  stop=current
-                end
-              end
-            end
-          end
-        end
-      end
-    end
-  end
-  while not basefound do
-    local char=getchar(current)
-    if consonant[char] then
-      setprop(current,a_state,s_half)
-      if not firstcons then
-        firstcons=current
-      end
-      lastcons=current
-      if not base then
-        base=current
-      elseif blwfcache[char] then
-        setprop(current,a_state,s_blwf)
-      else
-        base=current
-      end
-    end
-    basefound=current==stop
-    current=getnext(current)
-  end
-  if base~=lastcons then
-    local np=base
-    local n=getnext(base)
-    local ch=getchar(n)
-    if nukta[ch] then
-      np=n
-      n=getnext(n)
-      ch=getchar(n)
-    end
-    if halant[ch] then
-      if lastcons~=stop then
-        local ln=getnext(lastcons)
-        if nukta[getchar(ln)] then
-          lastcons=ln
-        end
-      end
-      local nn=getnext(n)
-      local ln=getnext(lastcons) 
-      setlink(np,nn)
-      setnext(lastcons,n)
-      if ln then
-        setprev(ln,n)
-      end
-      setnext(n,ln)
-      setprev(n,lastcons)
-      if lastcons==stop then
-        stop=n
-      end
-    end
-  end
-  n=getnext(start)
-  if n~=stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then
-    local matra=base
-    if base~=stop then
-      local next=getnext(base)
-      if dependent_vowel[getchar(next)] then
-        matra=next
-      end
-    end
-    local sp=getprev(start)
-    local nn=getnext(n)
-    local mn=getnext(matra)
-    setlink(sp,nn)
-    setlink(matra,start)
-    setlink(n,mn)
-    if head==start then
-      head=nn
-    end
-    start=nn
-    if matra==stop then
-      stop=n
-    end
-  end
-  local current=start
-  while current~=stop do
-    local next=getnext(current)
-    if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then
-      setprop(current,a_state,unsetvalue)
-    end
-    current=next
-  end
-  if base~=stop and getprop(base,a_state) then
-    local next=getnext(base)
-    if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then
-      setprop(base,a_state,unsetvalue)
-    end
-  end
-  local current,allreordered,moved=start,false,{ [base]=true }
-  local a,b,p,bn=base,base,base,getnext(base)
-  if base~=stop and nukta[getchar(bn)] then
-    a,b,p=bn,bn,bn
-  end
-  while not allreordered do
-    local c=current
-    local n=getnext(current)
-    local l=nil 
-    if c~=stop then
-      local ch=getchar(n)
-      if nukta[ch] then
-        c=n
-        n=getnext(n)
-        ch=getchar(n)
-      end
-      if c~=stop then
-        if halant[ch] then
-          c=n
-          n=getnext(n)
-          ch=getchar(n)
-        end
-        while c~=stop and dependent_vowel[ch] do
-          c=n
-          n=getnext(n)
-          ch=getchar(n)
-        end
-        if c~=stop then
-          if vowel_modifier[ch] then
-            c=n
-            n=getnext(n)
-            ch=getchar(n)
-          end
-          if c~=stop and stress_tone_mark[ch] then
-            c=n
-            n=getnext(n)
-          end
-        end
-      end
-    end
-    local bp=getprev(firstcons)
-    local cn=getnext(current)
-    local last=getnext(c)
-    while cn~=last do
-      if pre_mark[getchar(cn)] then
-        if bp then
-          setnext(bp,cn)
-        end
-        local prev,next=getboth(cn)
-        if next then
-          setprev(next,prev)
-        end
-        setnext(prev,next)
-        if cn==stop then
-          stop=prev
-        end
-        setprev(cn,bp)
-        setlink(cn,firstcons)
-        if firstcons==start then
-          if head==start then
-            head=cn
-          end
-          start=cn
-        end
-        break
-      end
-      cn=getnext(cn)
-    end
-    allreordered=c==stop
-    current=getnext(c)
-  end
-  if reph or vattu then
-    local current,cns=start,nil
-    while current~=stop do
-      local c=current
-      local n=getnext(current)
-      if ra[getchar(current)] and halant[getchar(n)] then
-        c=n
-        n=getnext(n)
-        local b,bn=base,base
-        while bn~=stop do
-          local next=getnext(bn)
-          if dependent_vowel[getchar(next)] then
-            b=next
-          end
-          bn=next
-        end
-        if getprop(current,a_state)==s_rphf then
-          if b~=current then
-            if current==start then
-              if head==start then
-                head=n
-              end
-              start=n
-            end
-            if b==stop then
-              stop=c
-            end
-            local prev=getprev(current)
-            setlink(prev,n)
-            local next=getnext(b)
-            setlink(c,next)
-            setlink(b,current)
-          end
-        elseif cns and getnext(cns)~=current then
-          local cp=getprev(current)
-          local cnsn=getnext(cns)
-          setlink(cp,n)
-          setlink(cns,current)
-          setlink(c,cnsn)
-          if c==stop then
-            stop=cp
-            break
-          end
-          current=getprev(n)
-        end
-      else
-        local char=getchar(current)
-        if consonant[char] then
-          cns=current
-          local next=getnext(cns)
-          if halant[getchar(next)] then
-            cns=next
-          end
-        elseif char==c_nbsp then
-          nbspaces=nbspaces+1
-          cns=current
-          local next=getnext(cns)
-          if halant[getchar(next)] then
-            cns=next
-          end
-        end
-      end
-      current=getnext(current)
-    end
-  end
-  if getchar(base)==c_nbsp then
-    nbspaces=nbspaces-1
-    head=remove_node(head,base)
-    flush_node(base)
-  end
-  return head,stop,nbspaces
-end
-function handlers.devanagari_reorder_matras(head,start) 
-  local current=start 
-  local startfont=getfont(start)
-  local startattr=getprop(start,a_syllabe)
-  while current do
-    local char=ischar(current,startfont)
-    local next=getnext(current)
-    if char and getprop(current,a_syllabe)==startattr then
-      if halant[char] and not getprop(current,a_state) then
-        if next then
-          local char=ischar(next,startfont)
-          if char and zw_char[char] and getprop(next,a_syllabe)==startattr then
-            current=next
-            next=getnext(current)
-          end
-        end
-        local startnext=getnext(start)
-        head=remove_node(head,start)
-        setlink(start,next)
-        setlink(current,start)
-        start=startnext
-        break
-      end
-    else
-      break
-    end
-    current=next
-  end
-  return head,start,true
-end
-function handlers.devanagari_reorder_reph(head,start)
-  local current=getnext(start)
-  local startnext=nil
-  local startprev=nil
-  local startfont=getfont(start)
-  local startattr=getprop(start,a_syllabe)
-  while current do
-    local char=ischar(current,startfont)
-    if char and getprop(current,a_syllabe)==startattr then 
-      if halant[char] and not getprop(current,a_state) then
-        local next=getnext(current)
-        if next then
-          local nextchar=ischar(next,startfont)
-          if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then
-            current=next
-            next=getnext(current)
-          end
-        end
-        startnext=getnext(start)
-        head=remove_node(head,start)
-        setlink(start,next)
-        setlink(current,start)
-        start=startnext
-        startattr=getprop(start,a_syllabe)
-        break
-      end
-      current=getnext(current)
-    else
-      break
-    end
-  end
-  if not startnext then
-    current=getnext(start)
-    while current do
-      local char=ischar(current,startfont)
-      if char and getprop(current,a_syllabe)==startattr then 
-        if getprop(current,a_state)==s_pstf then 
-          startnext=getnext(start)
-          head=remove_node(head,start)
-          local prev=getprev(current)
-          setlink(prev,start)
-          setlink(start,current)
-          start=startnext
-          startattr=getprop(start,a_syllabe)
-          break
-        end
-        current=getnext(current)
-      else
-        break
-      end
-    end
-  end
-  if not startnext then
-    current=getnext(start)
-    local c=nil
-    while current do
-      local char=ischar(current,startfont)
-      if char and getprop(current,a_syllabe)==startattr then 
-        if not c and mark_above_below_post[char] and reorder_class[char]~="after subscript" then
-          c=current
-        end
-        current=getnext(current)
-      else
-        break
-      end
-    end
-    if c then
-      startnext=getnext(start)
-      head=remove_node(head,start)
-      local prev=getprev(c)
-      setlink(prev,start)
-      setlink(start,c)
-      start=startnext
-      startattr=getprop(start,a_syllabe)
-    end
-  end
-  if not startnext then
-    current=start
-    local next=getnext(current)
-    while next do
-      local nextchar=ischar(next,startfont)
-      if nextchar and getprop(next,a_syllabe)==startattr then 
-        current=next
-        next=getnext(current)
-      else
-        break
-      end
-    end
-    if start~=current then
-      startnext=getnext(start)
-      head=remove_node(head,start)
-      local next=getnext(current)
-      setlink(start,next)
-      setlink(current,start)
-      start=startnext
-    end
-  end
-  return head,start,true
-end
-function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start)
-  local current=start
-  local startnext=nil
-  local startprev=nil
-  local startfont=getfont(start)
-  local startattr=getprop(start,a_syllabe)
-  while current do
-    local char=ischar(current,startfont)
-    if char and getprop(current,a_syllabe)==startattr then
-      local next=getnext(current)
-      if halant[char] and not getprop(current,a_state) then
-        if next then
-          local nextchar=ischar(next,startfont)
-          if nextchar and getprop(next,a_syllabe)==startattr then
-            if nextchar==c_zwnj or nextchar==c_zwj then
-              current=next
-              next=getnext(current)
-            end
-          end
-        end
-        startnext=getnext(start)
-        removenode(start,start)
-        setlink(start,next)
-        setlink(current,start)
-        start=startnext
-        break
-      end
-      current=next
-    else
-      break
-    end
-  end
-  if not startnext then
-    current=getnext(start)
-    startattr=getprop(start,a_syllabe)
-    while current do
-      local char=ischar(current,startfont)
-      if char and getprop(current,a_syllabe)==startattr then
-        if not consonant[char] and getprop(current,a_state) then 
-          startnext=getnext(start)
-          removenode(start,start)
-          local prev=getprev(current)
-          setlink(prev,start)
-          setlink(start,current)
-          start=startnext
-          break
-        end
-        current=getnext(current)
-      else
-        break
-      end
-    end
-  end
-  return head,start,true
-end
-function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replacement)
-  local stop=getnext(start)
-  local font=getfont(start)
-  local last=start
-  while stop do
-    local char=ischar(stop,font)
-    if char and (char==c_zwnj or char==c_zwj) then
-      last=stop
-      stop=getnext(stop)
-    else
-      break
-    end
-  end
-  local prev=getprev(start)
-  if stop then
-    setnext(last)
-    setlink(prev,stop)
-  elseif prev then
-    setnext(prev)
-  end
-  if head==start then
-  	head=stop
-  end
-  flush_list(start)
-  return head,stop,true
-end
-local function dev2_initialize(font,attr)
-  local devanagari=fontdata[font].resources.devanagari
-  if devanagari then
-    return devanagari.seqsubset or {},devanagari.reorderreph or {}
-  else
-    return {},{}
-  end
-end
-local function dev2_reorder(head,start,stop,font,attr,nbspaces) 
-  local seqsubset,reorderreph=dev2_initialize(font,attr)
-  local reph=false 
-  local halfpos=nil
-  local basepos=nil
-  local subpos=nil
-  local postpos=nil
-  local locl={}
-  for i=1,#seqsubset do
-    local subset=seqsubset[i]
-    local kind=subset[1]
-    local lookupcache=subset[2]
-    if kind=="rphf" then
-      reph=subset[3]
-      local current=start
-      local last=getnext(stop)
-      while current~=last do
-        if current~=stop then
-          local c=locl[current] or getchar(current)
-          local found=lookupcache[c]
-          if found then
-            local next=getnext(current)
-            local n=locl[next] or getchar(next)
-            if found[n] then  
-              local afternext=next~=stop and getnext(next)
-              if afternext and zw_char[getchar(afternext)] then 
-                current=next
-                current=getnext(current)
-              elseif current==start then
-                setprop(current,a_state,s_rphf)
-                current=next
-              else
-                current=next
-              end
-            end
-          end
-        end
-        current=getnext(current)
-      end
-    elseif kind=="pref" then
-      local current=start
-      local last=getnext(stop)
-      while current~=last do
-        if current~=stop then
-          local c=locl[current] or getchar(current)
-          local found=lookupcache[c]
-          if found then 
-            local next=getnext(current)
-            local n=locl[next] or getchar(next)
-            if found[n] then
-              setprop(current,a_state,s_pref)
-              setprop(next,a_state,s_pref)
-              current=next
-            end
-          end
-        end
-        current=getnext(current)
-      end
-    elseif kind=="half" then 
-      local current=start
-      local last=getnext(stop)
-      while current~=last do
-        if current~=stop then
-          local c=locl[current] or getchar(current)
-          local found=lookupcache[c]
-          if found then
-            local next=getnext(current)
-            local n=locl[next] or getchar(next)
-            if found[n] then
-              if next~=stop and getchar(getnext(next))==c_zwnj then  
-                current=next
-              else
-                setprop(current,a_state,s_half)
-                if not halfpos then
-                  halfpos=current
-                end
-              end
-              current=getnext(current)
-            end
-          end
-        end
-        current=getnext(current)
-      end
-    elseif kind=="blwf" then 
-      local current=start
-      local last=getnext(stop)
-      while current~=last do
-        if current~=stop then
-          local c=locl[current] or getchar(current)
-          local found=lookupcache[c]
-          if found then
-            local next=getnext(current)
-            local n=locl[next] or getchar(next)
-            if found[n] then
-              setprop(current,a_state,s_blwf)
-              setprop(next,a_state,s_blwf)
-              current=next
-              subpos=current
-            end
-          end
-        end
-        current=getnext(current)
-      end
-    elseif kind=="pstf" then 
-      local current=start
-      local last=getnext(stop)
-      while current~=last do
-        if current~=stop then
-          local c=locl[current] or getchar(current)
-          local found=lookupcache[c]
-          if found then
-            local next=getnext(current)
-            local n=locl[next] or getchar(next)
-            if found[n] then
-              setprop(current,a_state,s_pstf)
-              setprop(next,a_state,s_pstf)
-              current=next
-              postpos=current
-            end
-          end
-        end
-        current=getnext(current)
-      end
-    end
-  end
-  reorderreph.coverage={ [reph]=true }
-  local current,base,firstcons=start,nil,nil
-  if getprop(start,a_state)==s_rphf then
-    current=getnext(getnext(start))
-  end
-  if current~=getnext(stop) and getchar(current)==c_nbsp then
-    if current==stop then
-      stop=getprev(stop)
-      head=remove_node(head,current)
-      flush_node(current)
-      return head,stop,nbspaces
-    else
-      nbspaces=nbspaces+1
-      base=current
-      current=getnext(current)
-      if current~=stop then
-        local char=getchar(current)
-        if nukta[char] then
-          current=getnext(current)
-          char=getchar(current)
-        end
-        if char==c_zwj then
-          local next=getnext(current)
-          if current~=stop and next~=stop and halant[getchar(next)] then
-            current=next
-            next=getnext(current)
-            local tmp=getnext(next)
-            local changestop=next==stop
-            setnext(next,nil)
-            setprop(current,a_state,s_pref)
-            current=processcharacters(current,font)
-            setprop(current,a_state,s_blwf)
-            current=processcharacters(current,font)
-            setprop(current,a_state,s_pstf)
-            current=processcharacters(current,font)
-            setprop(current,a_state,unsetvalue)
-            if halant[getchar(current)] then
-              setnext(getnext(current),tmp)
-              local nc=copy_node(current)
-							copyinjection(nc,current)
-              setchar(current,dotted_circle)
-              head=insert_node_after(head,current,nc)
-            else
-              setnext(current,tmp) 
-              if changestop then
-                stop=current
-              end
-            end
-          end
-        end
-      end
-    end
-  else 
-    local last=getnext(stop)
-    while current~=last do  
-      local next=getnext(current)
-      if consonant[getchar(current)] then
-        if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then
-          if not firstcons then
-            firstcons=current
-          end
-          local a=getprop(current,a_state)
-          if not (a==s_pref or a==s_blwf or a==s_pstf) then
-            base=current
-          end
-        end
-      end
-      current=next
-    end
-    if not base then
-      base=firstcons
-    end
-  end
-  if not base then
-    if getprop(start,a_state)==s_rphf then
-      setprop(start,a_state,unsetvalue)
-    end
-    return head,stop,nbspaces
-  else
-    if getprop(base,a_state) then
-      setprop(base,a_state,unsetvalue)
-    end
-    basepos=base
-  end
-  if not halfpos then
-    halfpos=base
-  end
-  if not subpos then
-    subpos=base
-  end
-  if not postpos then
-    postpos=subpos or base
-  end
-  local moved={}
-  local current=start
-  local last=getnext(stop)
-  while current~=last do
-    local char,target,cn=locl[current] or getchar(current),nil,getnext(current)
-    local tpm=twopart_mark[char]
-    if tpm then
-      local extra=copy_node(current)
-      copyinjection(extra,current)
-      char=tpm[1]
-      setchar(current,char)
-      setchar(extra,tpm[2])
-      head=insert_node_after(head,current,extra)
-    end
-    if not moved[current] and dependent_vowel[char] then
-      if pre_mark[char] then      
-        moved[current]=true
-        local prev,next=getboth(current)
-        setlink(prev,next)
-        if current==stop then
-          stop=getprev(current)
-        end
-        if halfpos==start then
-          if head==start then
-            head=current
-          end
-          start=current
-        end
-        local prev=getprev(halfpos)
-        setlink(prev,current)
-        setlink(current,halfpos)
-        halfpos=current
-      elseif above_mark[char] then  
-        target=basepos
-        if subpos==basepos then
-          subpos=current
-        end
-        if postpos==basepos then
-          postpos=current
-        end
-        basepos=current
-      elseif below_mark[char] then  
-        target=subpos
-        if postpos==subpos then
-          postpos=current
-        end
-        subpos=current
-      elseif post_mark[char] then  
-        target=postpos
-        postpos=current
-      end
-      if mark_above_below_post[char] then
-        local prev=getprev(current)
-        if prev~=target then
-          local next=getnext(current)
-          setlink(prev,next)
-          if current==stop then
-            stop=prev
-          end
-          local next=getnext(target)
-          setlink(current,next)
-          setlink(target,current)
-        end
-      end
-    end
-    current=cn
-  end
-  local current,c=start,nil
-  while current~=stop do
-    local char=getchar(current)
-    if halant[char] or stress_tone_mark[char] then
-      if not c then
-        c=current
-      end
-    else
-      c=nil
-    end
-    local next=getnext(current)
-    if c and nukta[getchar(next)] then
-      if head==c then
-        head=next
-      end
-      if stop==next then
-        stop=current
-      end
-      local prev=getprev(c)
-      setlink(prev,next)
-      local nextnext=getnext(next)
-      setnext(current,nextnext)
-      local nextnextnext=getnext(nextnext)
-      if nextnextnext then
-        setprev(nextnextnext,current)
-      end
-      setlink(nextnext,c)
-    end
-    if stop==current then break end
-    current=getnext(current)
-  end
-  if getchar(base)==c_nbsp then
-    if base==stop then
-      stop=getprev(stop)
-    end
-    nbspaces=nbspaces-1
-    head=remove_node(head,base)
-    flush_node(base)
-  end
-  return head,stop,nbspaces
-end
-local separator={}
-imerge(separator,consonant)
-imerge(separator,independent_vowel)
-imerge(separator,dependent_vowel)
-imerge(separator,vowel_modifier)
-imerge(separator,stress_tone_mark)
-for k,v in next,nukta do separator[k]=true end
-for k,v in next,halant do separator[k]=true end
-local function analyze_next_chars_one(c,font,variant)
-  local n=getnext(c)
-  if not n then
-    return c
-  end
-  if variant==1 then
-    local v=ischar(n,font)
-    if v and nukta[v] then
-      n=getnext(n)
-      if n then
-        v=ischar(n,font)
-      end
-    end
-    if n and v then
-      local nn=getnext(n)
-      if nn then
-        local vv=ischar(nn,font)
-        if vv then
-          local nnn=getnext(nn)
-          if nnn then
-            local vvv=ischar(nnn,font)
-            if vvv then
-              if vv==c_zwj and consonant[vvv] then
-                c=nnn
-              elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then
-                local nnnn=getnext(nnn)
-                if nnnn then
-                  local vvvv=ischar(nnnn,font)
-                  if vvvv and consonant[vvvv] then
-                    c=nnnn
-                  end
-                end
-              end
-            end
-          end
-        end
-      end
-    end
-  elseif variant==2 then
-    local v=ischar(n,font)
-    if v and nukta[v] then
-      c=n
-    end
-    n=getnext(c)
-    if n then
-      v=ischar(n,font)
-      if v then
-        local nn=getnext(n)
-        if nn then
-          local vv=ischar(nn,font)
-          if vv and zw_char[v] then
-            n=nn
-            v=vv
-            nn=getnext(nn)
-            vv=nn and ischar(nn,font)
-          end
-          if vv and halant[v] and consonant[vv] then
-            c=nn
-          end
-        end
-      end
-    end
-  end
-  local n=getnext(c)
-  if not n then
-    return c
-  end
-  local v=ischar(n,font)
-  if not v then
-    return c
-  end
-  if dependent_vowel[v] then
-    c=getnext(c)
-    n=getnext(c)
-    if not n then
-      return c
-    end
-    v=ischar(n,font)
-    if not v then
-      return c
-    end
-  end
-  if nukta[v] then
-    c=getnext(c)
-    n=getnext(c)
-    if not n then
-      return c
-    end
-    v=ischar(n,font)
-    if not v then
-      return c
-    end
-  end
-  if halant[v] then
-    c=getnext(c)
-    n=getnext(c)
-    if not n then
-      return c
-    end
-    v=ischar(n,font)
-    if not v then
-      return c
-    end
-  end
-  if vowel_modifier[v] then
-    c=getnext(c)
-    n=getnext(c)
-    if not n then
-      return c
-    end
-    v=ischar(n,font)
-    if not v then
-      return c
-    end
-  end
-  if stress_tone_mark[v] then
-    c=getnext(c)
-    n=getnext(c)
-    if not n then
-      return c
-    end
-    v=ischar(n,font)
-    if not v then
-      return c
-    end
-  end
-  if stress_tone_mark[v] then
-    return n
-  else
-    return c
-  end
-end
-local function analyze_next_chars_two(c,font)
-  local n=getnext(c)
-  if not n then
-    return c
-  end
-  local v=ischar(n,font)
-  if v and nukta[v] then
-    c=n
-  end
-  n=c
-  while true do
-    local nn=getnext(n)
-    if nn then
-      local vv=ischar(nn,font)
-      if vv then
-        if halant[vv] then
-          n=nn
-          local nnn=getnext(nn)
-          if nnn then
-            local vvv=ischar(nnn,font)
-            if vvv and zw_char[vvv] then
-              n=nnn
-            end
-          end
-        elseif vv==c_zwnj or vv==c_zwj then
-          local nnn=getnext(nn)
-          if nnn then
-            local vvv=ischar(nnn,font)
-            if vvv and halant[vvv] then
-              n=nnn
-            end
-          end
-        else
-          break
-        end
-        local nn=getnext(n)
-        if nn then
-          local vv=ischar(nn,font)
-          if vv and consonant[vv] then
-            n=nn
-            local nnn=getnext(nn)
-            if nnn then
-              local vvv=ischar(nnn,font)
-              if vvv and nukta[vvv] then
-                n=nnn
-              end
-            end
-            c=n
-          else
-            break
-          end
-        else
-          break
-        end
-      else
-        break
-      end
-    else
-      break
-    end
-  end
-  if not c then
-    return
-  end
-  local n=getnext(c)
-  if not n then
-    return c
-  end
-  local v=ischar(n,font)
-  if not v then
-    return c
-  end
-  if v==c_anudatta then
-    c=n
-    n=getnext(c)
-    if not n then
-      return c
-    end
-    v=ischar(n,font)
-    if not v then
-      return c
-    end
-  end
-  if halant[v] then
-    c=n
-    n=getnext(c)
-    if not n then
-      return c
-    end
-    v=ischar(n,font)
-    if not v then
-      return c
-    end
-    if v==c_zwnj or v==c_zwj then
-      c=n
-      n=getnext(c)
-      if not n then
-        return c
-      end
-      v=ischar(n,font)
-      if not v then
-        return c
-      end
-    end
-  else
-    if dependent_vowel[v] then
-      c=n
-      n=getnext(c)
-      if not n then
-        return c
-      end
-      v=ischar(n,font)
-      if not v then
-        return c
-      end
-    end
-    if nukta[v] then
-      c=n
-      n=getnext(c)
-      if not n then
-        return c
-      end
-      v=ischar(n,font)
-      if not v then
-        return c
-      end
-    end
-    if halant[v] then
-      c=n
-      n=getnext(c)
-      if not n then
-        return c
-      end
-      v=ischar(n,font)
-      if not v then
-        return c
-      end
-    end
-  end
-  if vowel_modifier[v] then
-    c=n
-    n=getnext(c)
-    if not n then
-      return c
-    end
-    v=ischar(n,font)
-    if not v then
-      return c
-    end
-  end
-  if stress_tone_mark[v] then
-    c=n
-    n=getnext(c)
-    if not n then
-      return c
-    end
-    v=ischar(n,font)
-    if not v then
-      return c
-    end
-  end
-  if stress_tone_mark[v] then
-    return n
-  else
-    return c
-  end
-end
-local function inject_syntax_error(head,current,mark)
-  local signal=copy_node(current)
-	copyinjection(signal,current)
-  if mark==pre_mark then 
-    setchar(signal,dotted_circle)
-  else
-    setchar(current,dotted_circle)
-  end
-  return insert_node_after(head,current,signal)
-end
-function methods.deva(head,font,attr)
-  head=tonut(head)
-  local current=head
-  local start=true
-  local done=false
-  local nbspaces=0
-  while current do
-		local char=ischar(current,font)
-    if char then
-      done=true
-      local syllablestart=current
-      local syllableend=nil
-      local c=current
-      local n=getnext(c)
-	    local first=char
-      if n and ra[first] then
-        local second=ischar(n,font)
-        if second and halant[second] then
-          local n=getnext(n)
-          if n then
-            local third=ischar(n,font)
-            if third then
-              c=n
-              first=third
-            end
-          end
-        end
-      end
-      local standalone=first==c_nbsp
-      if standalone then
-        local prev=getprev(current)
-        if prev then
-          local prevchar=ischar(prev,font)
-          if not prevchar then
-          elseif not separator[prevchar] then
-          else
-            standalone=false
-          end
-        else
-        end
-      end
-      if standalone then
-				local syllableend=analyze_next_chars_one(c,font,2)
-				current=getnext(syllableend)
-        if syllablestart~=syllableend then
-          head,current,nbspaces=deva_reorder(head,syllablestart,syllableend,font,attr,nbspaces)
-          current=getnext(current)
-        end
-      else
-        if consonant[char] then
-          local prevc=true
-          while prevc do
-            prevc=false
-            local n=getnext(current)
-            if not n then
-              break
-            end
-            local v=ischar(n,font)
-            if not v then
-              break
-            end
-            if nukta[v] then
-              n=getnext(n)
-              if not n then
-                break
-              end
-              v=ischar(n,font)
-              if not v then
-                break
-              end
-            end
-            if halant[v] then
-              n=getnext(n)
-              if not n then
-                break
-              end
-              v=ischar(n,font)
-              if not v then
-                break
-              end
-              if v==c_zwnj or v==c_zwj then
-                n=getnext(n)
-                if not n then
-                  break
-                end
-                v=ischar(n,font)
-                if not v then
-                  break
-                end
-              end
-              if consonant[v] then
-                prevc=true
-                current=n
-              end
-            end
-          end
-          local n=getnext(current)
-          if n then
-            local v=ischar(n,font)
-            if v and nukta[v] then
-              current=n
-              n=getnext(current)
-            end
-          end
-          syllableend=current
-          current=n
-          if current then
-            local v=ischar(current,font)
-            if not v then
-            elseif halant[v] then
-              local n=getnext(current)
-              if n then
-                local v=ischar(n,font)
-                if v and zw_char[v] then
-                  syllableend=n
-                  current=getnext(n)
-                else
-                  syllableend=current
-                  current=n
-                end
-              else
-                syllableend=current
-                current=n
-              end
-            else
-              if dependent_vowel[v] then
-                syllableend=current
-                current=getnext(current)
-                v=ischar(current,font)
-              end
-              if v and vowel_modifier[v] then
-                syllableend=current
-                current=getnext(current)
-                v=ischar(current,font)
-              end
-              if v and stress_tone_mark[v] then
-                syllableend=current
-                current=getnext(current)
-              end
-            end
-          end
-          if syllablestart~=syllableend then
-            head,current,nbspaces=deva_reorder(head,syllablestart,syllableend,font,attr,nbspaces)
-            current=getnext(current)
-          end
-        elseif independent_vowel[char] then
-          syllableend=current
-          current=getnext(current)
-          if current then
-            local v=ischar(current,font)
-            if v then
-              if vowel_modifier[v] then
-                syllableend=current
-                current=getnext(current)
-                v=ischar(current,font)
-              end
-              if v and stress_tone_mark[v] then
-                syllableend=current
-                current=getnext(current)
-              end
-            end
-          end
-        else
-          local mark=mark_four[char]
-          if mark then
-            head,current=inject_syntax_error(head,current,mark)
-          end
-          current=getnext(current)
-        end
-      end
-    else
-      current=getnext(current)
-    end
-    start=false
-  end
-  if nbspaces>0 then
-    head=replace_all_nbsp(head)
-  end
-  head=tonode(head)
-  return head,done
-end
-function methods.dev2(head,font,attr)
-  head=tonut(head)
-  local current=head
-  local start=true
-  local done=false
-  local syllabe=0
-  local nbspaces=0
-  while current do
-    local syllablestart=nil
-    local syllableend=nil
-    local char=ischar(current,font)
-    if char then
-      done=true
-      syllablestart=current
-      local c=current
-      local n=getnext(current)
-      if n and ra[char] then
-        local nextchar=ischar(n,font)
-        if nextchar and halant[nextchar] then
-          local n=getnext(n)
-          if n then
-            local nextnextchar=ischar(n,font)
-            if nextnextchar then
-              c=n
-							char=nextnextchar
-            end
-          end
-        end
-      end
-      if independent_vowel[char] then
-        current=analyze_next_chars_one(c,font,1)
-        syllableend=current
-      else
-        local standalone=char==c_nbsp
-        if standalone then
-          nbspaces=nbspaces+1
-          local p=getprev(current)
-          if not p then
-          elseif ischar(p,font) then
-          elseif not separator[getchar(p)] then
-          else
-            standalone=false
-          end
-        end
-        if standalone then
-          current=analyze_next_chars_one(c,font,2)
-          syllableend=current
-        elseif consonant[getchar(current)] then
-          current=analyze_next_chars_two(current,font) 
-          syllableend=current
-        end
-      end
-    end
-    if syllableend then
-      syllabe=syllabe+1
-      local c=syllablestart
-      local n=getnext(syllableend)
-      while c~=n do
-        setprop(c,a_syllabe,syllabe)
-        c=getnext(c)
-      end
-    end
-    if syllableend and syllablestart~=syllableend then
-      head,current,nbspaces=dev2_reorder(head,syllablestart,syllableend,font,attr,nbspaces)
-    end
-    if not syllableend then
-      local char=ischar(current,font)
-      if char and not getprop(current,a_state) then
-        local mark=mark_four[char]
-        if mark then
-          head,current=inject_syntax_error(head,current,mark)
-        end
-      end
-    end
-    start=false
-    current=getnext(current)
-  end
-  if nbspaces>0 then
-    head=replace_all_nbsp(head)
-  end
-  head=tonode(head)
-  return head,done
-end
-methods.mlym=methods.deva
-methods.mlm2=methods.dev2
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-osd”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-ocl” fbc00782e4efb24a7569f99cd1574ffb] ---
-
-if not modules then modules={} end modules ['font-ocl']={
-  version=1.001,
-  comment="companion to font-otf.lua (context)",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local tostring,next,format=tostring,next,string.format
-local round,max=math.round,math.round
-local formatters=string.formatters
-local tounicode=fonts.mappings.tounicode
-local otf=fonts.handlers.otf
-local f_color=formatters["pdf:direct:%f %f %f rg"]
-local f_gray=formatters["pdf:direct:%f g"]
-local s_black="pdf:direct:0 g"
-if context then
-  local startactualtext=nil
-  local stopactualtext=nil
-  function otf.getactualtext(s)
-    if not startactualtext then
-      startactualtext=backends.codeinjections.startunicodetoactualtextdirect
-      stopactualtext=backends.codeinjections.stopunicodetoactualtextdirect
-    end
-    return startactualtext(s),stopactualtext()
-  end
-else
-  local tounicode=fonts.mappings.tounicode16
-  function otf.getactualtext(s)
-    return
-      "/Span << /ActualText <feff"..n.."> >> BDC",
-      "EMC"
-  end
-end
-local sharedpalettes={}
-if context then
-  local graytorgb=attributes.colors.graytorgb
-  local cmyktorgb=attributes.colors.cmyktorgb
-  function otf.registerpalette(name,values)
-    sharedpalettes[name]=values
-    for i=1,#values do
-      local v=values[i]
-      local r,g,b
-      local s=v.s
-      if s then
-        r,g,b=graytorgb(s)
-      else
-        local c,m,y,k=v.c,v.m,v.y,v.k
-        if c or m or y or k then
-          r,g,b=cmyktorgb(c or 0,m or 0,y or 0,k or 0)
-        else
-          r,g,b=v.r,v.g,v.b
-        end
-      end
-      values[i]={
-        max(r and round(r*255) or 0,255),
-        max(g and round(g*255) or 0,255),
-        max(b and round(b*255) or 0,255)
-      }
-    end
-  end
-else 
-  function otf.registerpalette(name,values)
-    sharedpalettes[name]=values
-    for i=1,#values do
-      local v=values[i]
-      values[i]={
-        max(round((v.r or 0)*255),255),
-        max(round((v.g or 0)*255),255),
-        max(round((v.b or 0)*255),255)
-      }
-    end
-  end
-end
-local function initializecolr(tfmdata,kind,value) 
-  if value then
-    local palettes=tfmdata.resources.colorpalettes
-    if palettes then
-      local palette=sharedpalettes[value] or palettes[tonumber(value) or 1] or palettes[1] or {}
-      local classes=#palette
-      if classes==0 then
-        return
-      end
-      local characters=tfmdata.characters
-      local descriptions=tfmdata.descriptions
-      local properties=tfmdata.properties
-      local colorvalues={}
-      properties.virtualized=true
-      tfmdata.fonts={
-        { id=0 }
-      }
-      for i=1,classes do
-        local p=palette[i]
-        local r,g,b=p[1],p[2],p[3]
-        if r==g and g==b then
-          colorvalues[i]={ "special",f_gray(r/255) }
-        else
-          colorvalues[i]={ "special",f_color(r/255,g/255,b/255) }
-        end
-      end
-      local getactualtext=otf.getactualtext
-      for unicode,character in next,characters do
-        local description=descriptions[unicode]
-        if description then
-          local colorlist=description.colors
-          if colorlist then
-            local b,e=getactualtext(tounicode(characters[unicode].unicode or 0xFFFD))
-            local w=character.width or 0
-            local s=#colorlist
-            local t={
-              { "special","pdf:page:q" },
-              { "special","pdf:raw:"..b }
-            }
-            local n=#t
-            for i=1,s do
-              local entry=colorlist[i]
-              n=n+1 t[n]=colorvalues[entry.class] or s_black
-              n=n+1 t[n]={ "char",entry.slot }
-              if s>1 and i<s and w~=0 then
-                n=n+1 t[n]={ "right",-w }
-              end
-            end
-            n=n+1 t[n]={ "special","pdf:page:"..e }
-            n=n+1 t[n]={ "special","pdf:raw:Q" }
-            character.commands=t
-          end
-        end
-      end
-    end
-  end
-end
-fonts.handlers.otf.features.register {
-  name="colr",
-  description="color glyphs",
-  manipulators={
-    base=initializecolr,
-    node=initializecolr,
-  }
-}
-local otfsvg=otf.svg or {}
-otf.svg=otfsvg
-otf.svgenabled=true
-do
-  local nofstreams=0
-  local f_name=formatters[ [[svg-glyph-%05i]] ]
-  local f_used=context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ]
-  local cache={}
-  function otfsvg.storepdfdata(pdf)
-    nofstreams=nofstreams+1
-    local o,n=epdf.openMemStream(pdf,#pdf,f_name(nofstreams))
-    cache[n]=o 
-    return nil,f_used(n),nil
-  end
-  if context then
-    local storepdfdata=otfsvg.storepdfdata
-    local initialized=false
-    function otfsvg.storepdfdata(pdf)
-      if not initialized then
-        if resolvers.setmemstream then
-          local f_setstream=formatters[ [[resolvers.setmemstream("svg-glyph-%05i",%q,true)]] ]
-          local f_getstream=formatters[ [[memstream:///svg-glyph-%05i]] ]
-          local f_nilstream=formatters[ [[resolvers.resetmemstream("svg-glyph-%05i",true)]] ]
-          storepdfdata=function(pdf)
-            nofstreams=nofstreams+1
-            return
-              f_setstream(nofstreams,pdf),
-              f_getstream(nofstreams),
-              f_nilstream(nofstreams)
-          end
-          otfsvg.storepdfdata=storepdfdata
-        end
-        initialized=true
-      end
-      return storepdfdata(pdf)
-    end
-  end
-end
-do
-  local report_svg=logs.reporter("fonts","svg conversion")
-  local loaddata=io.loaddata
-  local savedata=io.savedata
-  local remove=os.remove
-  if context and xml.convert then
-    local xmlconvert=xml.convert
-    local xmlfirst=xml.first
-    function otfsvg.filterglyph(entry,index)
-      local svg=xmlconvert(entry.data)
-      local root=svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']")
-      local data=root and tostring(root)
-      return data
-    end
-  else
-    function otfsvg.filterglyph(entry,index) 
-      return entry.data
-    end
-  end
-  function otfsvg.topdf(svgshapes)
-    local inkscape=io.popen("inkscape --shell > temp-otf-svg-shape.log","w")
-    local pdfshapes={}
-    local nofshapes=#svgshapes
-    local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"]
-    local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"]
-    local f_convert=formatters["%s --export-pdf=%s\n"]
-    local filterglyph=otfsvg.filterglyph
-    report_svg("processing %i svg containers",nofshapes)
-    statistics.starttiming()
-    for i=1,nofshapes do
-      local entry=svgshapes[i]
-      for index=entry.first,entry.last do
-        local data=filterglyph(entry,index)
-        if data and data~="" then
-          local svgfile=f_svgfile(index)
-          local pdffile=f_pdffile(index)
-          savedata(svgfile,data)
-          inkscape:write(f_convert(svgfile,pdffile))
-          pdfshapes[index]=true
-        end
-      end
-    end
-    inkscape:write("quit\n")
-    inkscape:close()
-    report_svg("processing %i pdf results",nofshapes)
-    for index in next,pdfshapes do
-      local svgfile=f_svgfile(index)
-      local pdffile=f_pdffile(index)
-      pdfshapes[index]=loaddata(pdffile)
-      remove(svgfile)
-      remove(pdffile)
-    end
-    statistics.stoptiming()
-    if statistics.elapsedseconds then
-      report_svg("svg conversion time %s",statistics.elapsedseconds())
-    end
-    return pdfshapes
-  end
-end
-local function initializesvg(tfmdata,kind,value) 
-  if value and otf.svgenabled then
-    local characters=tfmdata.characters
-    local descriptions=tfmdata.descriptions
-    local properties=tfmdata.properties
-    local svg=properties.svg
-    local hash=svg and svg.hash
-    local timestamp=svg and svg.timestamp
-    if not hash then
-      return
-    end
-    local pdffile=containers.read(otf.pdfcache,hash)
-    local pdfshapes=pdffile and pdffile.pdfshapes
-    if not pdfshapes or pdffile.timestamp~=timestamp then
-      local svgfile=containers.read(otf.svgcache,hash)
-      local svgshapes=svgfile and svgfile.svgshapes
-      pdfshapes=svgshapes and otfsvg.topdf(svgshapes) or {}
-      containers.write(otf.pdfcache,hash,{
-        pdfshapes=pdfshapes,
-        timestamp=timestamp,
-      })
-    end
-    if not pdfshapes or not next(pdfshapes) then
-      return
-    end
-    properties.virtualized=true
-    tfmdata.fonts={
-      { id=0 }
-    }
-    local getactualtext=otf.getactualtext
-    local storepdfdata=otfsvg.storepdfdata
-    local nop={ "nop" }
-    for unicode,character in next,characters do
-      local index=character.index
-      if index then
-        local pdf=pdfshapes[index]
-        if pdf then
-          local setcode,name,nilcode=storepdfdata(pdf)
-          if name then
-            local bt,et=getactualtext(unicode)
-            local wd=character.width or 0
-            local ht=character.height or 0
-            local dp=character.depth or 0
-            character.commands={
-              { "special","pdf:direct:"..bt },
-              { "down",dp },
-              setcode and { "lua",setcode } or nop,
-              { "image",{ filename=name,width=wd,height=ht,depth=dp } },
-              nilcode and { "lua",nilcode } or nop,
-              { "special","pdf:direct:"..et },
-            }
-            character.svg=true
-          end
-        end
-      end
-    end
-  end
-end
-fonts.handlers.otf.features.register {
-  name="svg",
-  description="svg glyphs",
-  manipulators={
-    base=initializesvg,
-    node=initializesvg,
-  }
-}
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-ocl”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-otc” 85d63e257c748c624768aa7c8ec7f0bc] ---
-
-if not modules then modules={} end modules ['font-otc']={
-  version=1.001,
-  comment="companion to font-otf.lua (context)",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local format,insert,sortedkeys,tohash=string.format,table.insert,table.sortedkeys,table.tohash
-local type,next=type,next
-local lpegmatch=lpeg.match
-local utfbyte,utflen=utf.byte,utf.len
-local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
-local report_otf=logs.reporter("fonts","otf loading")
-local fonts=fonts
-local otf=fonts.handlers.otf
-local registerotffeature=otf.features.register
-local setmetatableindex=table.setmetatableindex
-local normalized={
-  substitution="substitution",
-  single="substitution",
-  ligature="ligature",
-  alternate="alternate",
-  multiple="multiple",
-  kern="kern",
-  pair="pair",
-  chainsubstitution="chainsubstitution",
-  chainposition="chainposition",
-}
-local types={
-  substitution="gsub_single",
-  ligature="gsub_ligature",
-  alternate="gsub_alternate",
-  multiple="gsub_multiple",
-  kern="gpos_pair",
-  pair="gpos_pair",
-  chainsubstitution="gsub_contextchain",
-  chainposition="gpos_contextchain",
-}
-local names={
-  gsub_single="gsub",
-  gsub_multiple="gsub",
-  gsub_alternate="gsub",
-  gsub_ligature="gsub",
-  gsub_context="gsub",
-  gsub_contextchain="gsub",
-  gsub_reversecontextchain="gsub",
-  gpos_single="gpos",
-  gpos_pair="gpos",
-  gpos_cursive="gpos",
-  gpos_mark2base="gpos",
-  gpos_mark2ligature="gpos",
-  gpos_mark2mark="gpos",
-  gpos_context="gpos",
-  gpos_contextchain="gpos",
-}
-setmetatableindex(types,function(t,k) t[k]=k return k end) 
-local everywhere={ ["*"]={ ["*"]=true } } 
-local noflags={ false,false,false,false }
-local function getrange(sequences,category)
-  local count=#sequences
-  local first=nil
-  local last=nil
-  for i=1,count do
-    local t=sequences[i].type
-    if t and names[t]==category then
-      if not first then
-        first=i
-      end
-      last=i
-    end
-  end
-  return first or 1,last or count
-end
-local function validspecification(specification,name)
-  local dataset=specification.dataset
-  if dataset then
-  elseif specification[1] then
-    dataset=specification
-    specification={ dataset=dataset }
-  else
-    dataset={ { data=specification.data } }
-    specification.data=nil
-    specification.dataset=dataset
-  end
-  local first=dataset[1]
-  if first then
-    first=first.data
-  end
-  if not first then
-    report_otf("invalid feature specification, no dataset")
-    return
-  end
-  if type(name)~="string" then
-    name=specification.name or first.name
-  end
-  if type(name)~="string" then
-    report_otf("invalid feature specification, no name")
-    return
-  end
-  local n=#dataset
-  if n>0 then
-    for i=1,n do
-      setmetatableindex(dataset[i],specification)
-    end
-    return specification,name
-  end
-end
-local function addfeature(data,feature,specifications)
-  if not specifications then
-    report_otf("missing specification")
-    return
-  end
-  local descriptions=data.descriptions
-  local resources=data.resources
-  local features=resources.features
-  local sequences=resources.sequences
-  if not features or not sequences then
-    report_otf("missing specification")
-    return
-  end
-  local alreadydone=resources.alreadydone
-  if not alreadydone then
-    alreadydone={}
-    resources.alreadydone=alreadydone
-  end
-  if alreadydone[specifications] then
-    return
-  else
-    alreadydone[specifications]=true
-  end
-  local fontfeatures=resources.features or everywhere
-  local unicodes=resources.unicodes
-  local splitter=lpeg.splitter(" ",unicodes)
-  local done=0
-  local skip=0
-  local aglunicodes=false
-  local specifications=validspecification(specifications,feature)
-  if not specifications then
-    return
-  end
-  local function tounicode(code)
-    if not code then
-      return
-    end
-    if type(code)=="number" then
-      return code
-    end
-    local u=unicodes[code]
-    if u then
-      return u
-    end
-    if utflen(code)==1 then
-      u=utfbyte(code)
-      if u then
-        return u
-      end
-    end
-    if not aglunicodes then
-      aglunicodes=fonts.encodings.agl.unicodes 
-    end
-    return aglunicodes[code]
-  end
-  local coverup=otf.coverup
-  local coveractions=coverup.actions
-  local stepkey=coverup.stepkey
-  local register=coverup.register
-  local function prepare_substitution(list,featuretype)
-    local coverage={}
-    local cover=coveractions[featuretype]
-    for code,replacement in next,list do
-      local unicode=tounicode(code)
-      local description=descriptions[unicode]
-      if description then
-        if type(replacement)=="table" then
-          replacement=replacement[1]
-        end
-        replacement=tounicode(replacement)
-        if replacement and descriptions[replacement] then
-          cover(coverage,unicode,replacement)
-          done=done+1
-        else
-          skip=skip+1
-        end
-      else
-        skip=skip+1
-      end
-    end
-    return coverage
-  end
-  local function prepare_alternate(list,featuretype)
-    local coverage={}
-    local cover=coveractions[featuretype]
-    for code,replacement in next,list do
-      local unicode=tounicode(code)
-      local description=descriptions[unicode]
-      if not description then
-        skip=skip+1
-      elseif type(replacement)=="table" then
-        local r={}
-        for i=1,#replacement do
-          local u=tounicode(replacement[i])
-          r[i]=descriptions[u] and u or unicode
-        end
-        cover(coverage,unicode,r)
-        done=done+1
-      else
-        local u=tounicode(replacement)
-        if u then
-          cover(coverage,unicode,{ u })
-          done=done+1
-        else
-          skip=skip+1
-        end
-      end
-    end
-    return coverage
-  end
-  local function prepare_multiple(list,featuretype)
-    local coverage={}
-    local cover=coveractions[featuretype]
-    for code,replacement in next,list do
-      local unicode=tounicode(code)
-      local description=descriptions[unicode]
-      if not description then
-        skip=skip+1
-      elseif type(replacement)=="table" then
-        local r,n={},0
-        for i=1,#replacement do
-          local u=tounicode(replacement[i])
-          if descriptions[u] then
-            n=n+1
-            r[n]=u
-          end
-        end
-        if n>0 then
-          cover(coverage,unicode,r)
-          done=done+1
-        else
-          skip=skip+1
-        end
-      else
-        local u=tounicode(replacement)
-        if u then
-          cover(coverage,unicode,{ u })
-          done=done+1
-        else
-          skip=skip+1
-        end
-      end
-    end
-    return coverage
-  end
-  local function prepare_ligature(list,featuretype)
-    local coverage={}
-    local cover=coveractions[featuretype]
-    for code,ligature in next,list do
-      local unicode=tounicode(code)
-      local description=descriptions[unicode]
-      if description then
-        if type(ligature)=="string" then
-          ligature={ lpegmatch(splitter,ligature) }
-        end
-        local present=true
-        for i=1,#ligature do
-          local l=ligature[i]
-          local u=tounicode(l)
-          if descriptions[u] then
-            ligature[i]=u
-          else
-            present=false
-            break
-          end
-        end
-        if present then
-          cover(coverage,unicode,ligature)
-          done=done+1
-        else
-          skip=skip+1
-        end
-      else
-        skip=skip+1
-      end
-    end
-    return coverage
-  end
-  local function prepare_kern(list,featuretype)
-    local coverage={}
-    local cover=coveractions[featuretype]
-    for code,replacement in next,list do
-      local unicode=tounicode(code)
-      local description=descriptions[unicode]
-      if description and type(replacement)=="table" then
-        local r={}
-        for k,v in next,replacement do
-          local u=tounicode(k)
-          if u then
-            r[u]=v
-          end
-        end
-        if next(r) then
-          cover(coverage,unicode,r)
-          done=done+1
-        else
-          skip=skip+1
-        end
-      else
-        skip=skip+1
-      end
-    end
-    return coverage
-  end
-  local function prepare_pair(list,featuretype)
-    local coverage={}
-    local cover=coveractions[featuretype]
-    if cover then
-      for code,replacement in next,list do
-        local unicode=tounicode(code)
-        local description=descriptions[unicode]
-        if description and type(replacement)=="table" then
-          local r={}
-          for k,v in next,replacement do
-            local u=tounicode(k)
-            if u then
-              r[u]=v
-            end
-          end
-          if next(r) then
-            cover(coverage,unicode,r)
-            done=done+1
-          else
-            skip=skip+1
-          end
-        else
-          skip=skip+1
-        end
-      end
-    else
-      report_otf("unknown cover type %a",featuretype)
-    end
-    return coverage
-  end
-  local function prepare_chain(list,featuretype,sublookups)
-    local rules=list.rules
-    local coverage={}
-    if rules then
-      local rulehash={}
-      local rulesize=0
-      local sequence={}
-      local nofsequences=0
-      local lookuptype=types[featuretype]
-      for nofrules=1,#rules do
-        local rule=rules[nofrules]
-        local current=rule.current
-        local before=rule.before
-        local after=rule.after
-        local replacements=rule.replacements or false
-        local sequence={}
-        local nofsequences=0
-        if before then
-          for n=1,#before do
-            nofsequences=nofsequences+1
-            sequence[nofsequences]=before[n]
-          end
-        end
-        local start=nofsequences+1
-        for n=1,#current do
-          nofsequences=nofsequences+1
-          sequence[nofsequences]=current[n]
-        end
-        local stop=nofsequences
-        if after then
-          for n=1,#after do
-            nofsequences=nofsequences+1
-            sequence[nofsequences]=after[n]
-          end
-        end
-        local lookups=rule.lookups or false
-        local subtype=nil
-        if lookups and sublookups then
-          for k,v in next,lookups do
-            local lookup=sublookups[v]
-            if lookup then
-              lookups[k]=lookup
-              if not subtype then
-                subtype=lookup.type
-              end
-            else
-            end
-          end
-        end
-        if nofsequences>0 then
-          local hashed={}
-          for i=1,nofsequences do
-            local t={}
-            local s=sequence[i]
-            for i=1,#s do
-              local u=tounicode(s[i])
-              if u then
-                t[u]=true
-              end
-            end
-            hashed[i]=t
-          end
-          sequence=hashed
-          rulesize=rulesize+1
-          rulehash[rulesize]={
-            nofrules,
-            lookuptype,
-            sequence,
-            start,
-            stop,
-            lookups,
-            replacements,
-            subtype,
-          }
-          for unic in next,sequence[start] do
-            local cu=coverage[unic]
-            if not cu then
-              coverage[unic]=rulehash 
-            end
-          end
-        end
-      end
-    end
-    return coverage
-  end
-  local dataset=specifications.dataset
-  local function report(name,category,position,first,last,sequences)
-    report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]",
-      name,category,position,first,last,1,#sequences)
-  end
-  local function inject(specification,sequences,sequence,first,last,category,name)
-    local position=specification.position or false
-    if not position then
-      position=specification.prepend
-      if position==true then
-        if trace_loading then
-          report(name,category,first,first,last,sequences)
-        end
-        insert(sequences,first,sequence)
-        return
-      end
-    end
-    if not position then
-      position=specification.append
-      if position==true then
-        if trace_loading then
-          report(name,category,last+1,first,last,sequences)
-        end
-        insert(sequences,last+1,sequence)
-        return
-      end
-    end
-    local kind=type(position)
-    if kind=="string" then
-      local index=false
-      for i=first,last do
-        local s=sequences[i]
-        local f=s.features
-        if f then
-          for k in next,f do
-            if k==position then
-              index=i
-              break
-            end
-          end
-          if index then
-            break
-          end
-        end
-      end
-      if index then
-        position=index
-      else
-        position=last+1
-      end
-    elseif kind=="number" then
-      if position<0 then
-        position=last-position+1
-      end
-      if position>last then
-        position=last+1
-      elseif position<first then
-        position=first
-      end
-    else
-      position=last+1
-    end
-    if trace_loading then
-      report(name,category,position,first,last,sequences)
-    end
-    insert(sequences,position,sequence)
-  end
-  for s=1,#dataset do
-    local specification=dataset[s]
-    local valid=specification.valid 
-    local feature=specification.name or feature
-    if not feature or feature=="" then
-      report_otf("no valid name given for extra feature")
-    elseif not valid or valid(data,specification,feature) then 
-      local initialize=specification.initialize
-      if initialize then
-        specification.initialize=initialize(specification,data) and initialize or nil
-      end
-      local askedfeatures=specification.features or everywhere
-      local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
-      local featuretype=normalized[specification.type or "substitution"] or "substitution"
-      local featureflags=specification.flags or noflags
-      local featureorder=specification.order or { feature }
-      local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0
-      local nofsteps=0
-      local steps={}
-      local sublookups=specification.lookups
-      local category=nil
-      if sublookups then
-        local s={}
-        for i=1,#sublookups do
-          local specification=sublookups[i]
-          local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
-          local featuretype=normalized[specification.type or "substitution"] or "substitution"
-          local featureflags=specification.flags or noflags
-          local nofsteps=0
-          local steps={}
-          for i=1,#askedsteps do
-            local list=askedsteps[i]
-            local coverage=nil
-            local format=nil
-            if featuretype=="substitution" then
-              coverage=prepare_substitution(list,featuretype)
-            elseif featuretype=="ligature" then
-              coverage=prepare_ligature(list,featuretype)
-            elseif featuretype=="alternate" then
-              coverage=prepare_alternate(list,featuretype)
-            elseif featuretype=="multiple" then
-              coverage=prepare_multiple(list,featuretype)
-            elseif featuretype=="kern" then
-              format="kern"
-              coverage=prepare_kern(list,featuretype)
-            elseif featuretype=="pair" then
-              format="pair"
-              coverage=prepare_pair(list,featuretype)
-            end
-            if coverage and next(coverage) then
-              nofsteps=nofsteps+1
-              steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
-            end
-          end
-          s[i]={
-            [stepkey]=steps,
-            nofsteps=nofsteps,
-            type=types[featuretype],
-          }
-        end
-        sublookups=s
-      end
-      for i=1,#askedsteps do
-        local list=askedsteps[i]
-        local coverage=nil
-        local format=nil
-        if featuretype=="substitution" then
-          category="gsub"
-          coverage=prepare_substitution(list,featuretype)
-        elseif featuretype=="ligature" then
-          category="gsub"
-          coverage=prepare_ligature(list,featuretype)
-        elseif featuretype=="alternate" then
-          category="gsub"
-          coverage=prepare_alternate(list,featuretype)
-        elseif featuretype=="multiple" then
-          category="gsub"
-          coverage=prepare_multiple(list,featuretype)
-        elseif featuretype=="kern" then
-          category="gpos"
-          format="kern"
-          coverage=prepare_kern(list,featuretype)
-        elseif featuretype=="pair" then
-          category="gpos"
-          format="pair"
-          coverage=prepare_pair(list,featuretype)
-        elseif featuretype=="chainsubstitution" then
-          category="gsub"
-          coverage=prepare_chain(list,featuretype,sublookups)
-        elseif featuretype=="chainposition" then
-          category="gpos"
-          coverage=prepare_chain(list,featuretype,sublookups)
-        else
-          report_otf("not registering feature %a, unknown category",feature)
-          return
-        end
-        if coverage and next(coverage) then
-          nofsteps=nofsteps+1
-          steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
-        end
-      end
-      if nofsteps>0 then
-        for k,v in next,askedfeatures do
-          if v[1] then
-            askedfeatures[k]=tohash(v)
-          end
-        end
-        if featureflags[1] then featureflags[1]="mark" end
-        if featureflags[2] then featureflags[2]="ligature" end
-        if featureflags[3] then featureflags[3]="base" end
-        local steptype=types[featuretype]
-        local sequence={
-          chain=featurechain,
-          features={ [feature]=askedfeatures },
-          flags=featureflags,
-          name=feature,
-          order=featureorder,
-          [stepkey]=steps,
-          nofsteps=nofsteps,
-          type=steptype,
-        }
-        local first,last=getrange(sequences,category)
-        inject(specification,sequences,sequence,first,last,category,feature)
-        local features=fontfeatures[category]
-        if not features then
-          features={}
-          fontfeatures[category]=features
-        end
-        local k=features[feature]
-        if not k then
-          k={}
-          features[feature]=k
-        end
-        for script,languages in next,askedfeatures do
-          local kk=k[script]
-          if not kk then
-            kk={}
-            k[script]=kk
-          end
-          for language,value in next,languages do
-            kk[language]=value
-          end
-        end
-      end
-    end
-  end
-  if trace_loading then
-    report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip)
-  end
-end
-otf.enhancers.addfeature=addfeature
-local extrafeatures={}
-local knownfeatures={}
-function otf.addfeature(name,specification)
-  if type(name)=="table" then
-    specification=name
-  end
-  if type(specification)~="table" then
-    report_otf("invalid feature specification, no valid table")
-    return
-  end
-  specification,name=validspecification(specification,name)
-  if name and specification then
-    local slot=knownfeatures[name]
-    if slot then
-    else
-      slot=#extrafeatures+1
-      knownfeatures[name]=slot
-    end
-    specification.name=name 
-    extrafeatures[slot]=specification
-  end
-end
-local function enhance(data,filename,raw)
-  for slot=1,#extrafeatures do
-    local specification=extrafeatures[slot]
-    addfeature(data,specification.name,specification)
-  end
-end
-otf.enhancers.enhance=enhance
-otf.enhancers.register("check extra features",enhance)
-local tlig={
-  [0x2013]={ 0x002D,0x002D },
-  [0x2014]={ 0x002D,0x002D,0x002D },
-}
-local tlig_specification={
-  type="ligature",
-  features=everywhere,
-  data=tlig,
-  order={ "tlig" },
-  flags=noflags,
-  prepend=true,
-}
-otf.addfeature("tlig",tlig_specification)
-registerotffeature {
-  name='tlig',
-  description='tex ligatures',
-}
-local trep={
-  [0x0027]=0x2019,
-}
-local trep_specification={
-  type="substitution",
-  features=everywhere,
-  data=trep,
-  order={ "trep" },
-  flags=noflags,
-  prepend=true,
-}
-otf.addfeature("trep",trep_specification)
-registerotffeature {
-  name='trep',
-  description='tex replacements',
-}
-local anum_arabic={
-  [0x0030]=0x0660,
-  [0x0031]=0x0661,
-  [0x0032]=0x0662,
-  [0x0033]=0x0663,
-  [0x0034]=0x0664,
-  [0x0035]=0x0665,
-  [0x0036]=0x0666,
-  [0x0037]=0x0667,
-  [0x0038]=0x0668,
-  [0x0039]=0x0669,
-}
-local anum_persian={
-  [0x0030]=0x06F0,
-  [0x0031]=0x06F1,
-  [0x0032]=0x06F2,
-  [0x0033]=0x06F3,
-  [0x0034]=0x06F4,
-  [0x0035]=0x06F5,
-  [0x0036]=0x06F6,
-  [0x0037]=0x06F7,
-  [0x0038]=0x06F8,
-  [0x0039]=0x06F9,
-}
-local function valid(data)
-  local features=data.resources.features
-  if features then
-    for k,v in next,features do
-      for k,v in next,v do
-        if v.arab then
-          return true
-        end
-      end
-    end
-  end
-end
-local anum_specification={
-  {
-    type="substitution",
-    features={ arab={ urd=true,dflt=true } },
-    order={ "anum" },
-    data=anum_arabic,
-    flags=noflags,
-    valid=valid,
-  },
-  {
-    type="substitution",
-    features={ arab={ urd=true } },
-    order={ "anum" },
-    data=anum_persian,
-    flags=noflags,
-    valid=valid,
-  },
-}
-otf.addfeature("anum",anum_specification) 
-registerotffeature {
-  name='anum',
-  description='arabic digits',
-}
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-otc”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-onr” 205c8bc640715aecf3538a33b842f450] ---
-
-if not modules then modules={} end modules ['font-onr']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers
-local next,type,tonumber,rawget,rawset=next,type,tonumber,rawget,rawset
-local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.strip,string.find
-local char,byte,sub=string.char,string.byte,string.sub
-local abs=math.abs
-local bxor,rshift=bit32.bxor,bit32.rshift
-local P,S,R,Cmt,C,Ct,Cs,Carg,Cf,Cg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg
-local lpegmatch,patterns=lpeg.match,lpeg.patterns
-local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
-local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
-local report_afm=logs.reporter("fonts","afm loading")
-local report_pfb=logs.reporter("fonts","pfb loading")
-local handlers=fonts.handlers
-local afm=handlers.afm or {}
-handlers.afm=afm
-local readers=afm.readers or {}
-afm.readers=readers
-afm.version=1.512
-local get_indexes,get_shapes
-do
-  local decrypt
-  do
-    local r,c1,c2,n=0,0,0,0
-    local function step(c)
-      local cipher=byte(c)
-      local plain=bxor(cipher,rshift(r,8))
-      r=((cipher+r)*c1+c2)%65536
-      return char(plain)
-    end
-    decrypt=function(binary,initial,seed)
-      r,c1,c2,n=initial,52845,22719,seed
-      binary=gsub(binary,".",step)
-      return sub(binary,n+1)
-    end
-  end
-  local charstrings=P("/CharStrings")
-  local subroutines=P("/Subrs")
-  local encoding=P("/Encoding")
-  local dup=P("dup")
-  local put=P("put")
-  local array=P("array")
-  local name=P("/")*C((R("az")+R("AZ")+R("09")+S("-_."))^1)
-  local digits=R("09")^1
-  local cardinal=digits/tonumber
-  local spaces=P(" ")^1
-  local spacing=patterns.whitespace^0
-  local routines,vector,chars,n,m
-  local initialize=function(str,position,size)
-    n=0
-    m=size 
-    return position+1
-  end
-  local setroutine=function(str,position,index,size)
-    local forward=position+tonumber(size)
-    local stream=sub(str,position+1,forward)
-    routines[index]=decrypt(stream,4330,4)
-    return forward
-  end
-  local setvector=function(str,position,name,size)
-    local forward=position+tonumber(size)
-    if n>=m then
-      return #str
-    elseif forward<#str then
-      vector[n]=name
-      n=n+1 
-      return forward
-    else
-      return #str
-    end
-  end
-  local setshapes=function(str,position,name,size)
-    local forward=position+tonumber(size)
-    local stream=sub(str,position+1,forward)
-    if n>m then
-      return #str
-    elseif forward<#str then
-      vector[n]=name
-      n=n+1
-      chars [n]=decrypt(stream,4330,4)
-      return forward
-    else
-      return #str
-    end
-  end
-  local p_rd=spacing*(P("RD")+P("-|"))
-  local p_np=spacing*(P("NP")+P("|"))
-  local p_nd=spacing*(P("ND")+P("|"))
-  local p_filterroutines=
-    (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd,setroutine)*p_np+P(1))^1
-  local p_filtershapes=
-    (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd,setshapes)*p_nd+P(1))^1
-  local p_filternames=Ct (
-    (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal,setvector)+P(1))^1
-  )
-  local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf(
-      Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1
-,rawset)
-  local function loadpfbvector(filename,shapestoo)
-    local data=io.loaddata(resolvers.findfile(filename))
-    if not data then
-      report_pfb("no data in %a",filename)
-      return
-    end
-    if not (find(data,"!PS%-AdobeFont%-") or find(data,"%%!FontType1")) then
-      report_pfb("no font in %a",filename)
-      return
-    end
-    local ascii,binary=match(data,"(.*)eexec%s+......(.*)")
-    if not binary then
-      report_pfb("no binary data in %a",filename)
-      return
-    end
-    binary=decrypt(binary,55665,4)
-    local names={}
-    local encoding=lpegmatch(p_filterencoding,ascii)
-    local glyphs={}
-    routines,vector,chars={},{},{}
-    if shapestoo then
-      lpegmatch(p_filterroutines,binary)
-      lpegmatch(p_filtershapes,binary)
-      local data={
-        dictionaries={
-          {
-            charstrings=chars,
-            charset=vector,
-            subroutines=routines,
-          }
-        },
-      }
-      fonts.handlers.otf.readers.parsecharstrings(data,glyphs,true,true)
-    else
-      lpegmatch(p_filternames,binary)
-    end
-    names=vector
-    routines,vector,chars=nil,nil,nil
-    return names,encoding,glyphs
-  end
-  local pfb=handlers.pfb or {}
-  handlers.pfb=pfb
-  pfb.loadvector=loadpfbvector
-  get_indexes=function(data,pfbname)
-    local vector=loadpfbvector(pfbname)
-    if vector then
-      local characters=data.characters
-      if trace_loading then
-        report_afm("getting index data from %a",pfbname)
-      end
-      for index=1,#vector do
-        local name=vector[index]
-        local char=characters[name]
-        if char then
-          if trace_indexing then
-            report_afm("glyph %a has index %a",name,index)
-          end
-          char.index=index
-        end
-      end
-    end
-  end
-  get_shapes=function(pfbname)
-    local vector,encoding,glyphs=loadpfbvector(pfbname,true)
-    return glyphs
-  end
-end
-local spacer=patterns.spacer
-local whitespace=patterns.whitespace
-local lineend=patterns.newline
-local spacing=spacer^0
-local number=spacing*S("+-")^-1*(R("09")+S("."))^1/tonumber
-local name=spacing*C((1-whitespace)^1)
-local words=spacing*((1-lineend)^1/strip)
-local rest=(1-lineend)^0
-local fontdata=Carg(1)
-local semicolon=spacing*P(";")
-local plus=spacing*P("plus")*number
-local minus=spacing*P("minus")*number
-local function addkernpair(data,one,two,value)
-  local chr=data.characters[one]
-  if chr then
-    local kerns=chr.kerns
-    if kerns then
-      kerns[two]=tonumber(value)
-    else
-      chr.kerns={ [two]=tonumber(value) }
-    end
-  end
-end
-local p_kernpair=(fontdata*P("KPX")*name*name*number)/addkernpair
-local chr=false
-local ind=0
-local function start(data,version)
-  data.metadata.afmversion=version
-  ind=0
-  chr={}
-end
-local function stop()
-  ind=0
-  chr=false
-end
-local function setindex(i)
-  if i<0 then
-    ind=ind+1 
-  else
-    ind=i
-  end
-  chr={
-    index=ind
-  }
-end
-local function setwidth(width)
-  chr.width=width
-end
-local function setname(data,name)
-  data.characters[name]=chr
-end
-local function setboundingbox(boundingbox)
-  chr.boundingbox=boundingbox
-end
-local function setligature(plus,becomes)
-  local ligatures=chr.ligatures
-  if ligatures then
-    ligatures[plus]=becomes
-  else
-    chr.ligatures={ [plus]=becomes }
-  end
-end
-local p_charmetric=((
-  P("C")*number/setindex+P("WX")*number/setwidth+P("N")*fontdata*name/setname+P("B")*Ct((number)^4)/setboundingbox+P("L")*(name)^2/setligature
- )*semicolon )^1
-local p_charmetrics=P("StartCharMetrics")*number*(p_charmetric+(1-P("EndCharMetrics")))^0*P("EndCharMetrics")
-local p_kernpairs=P("StartKernPairs")*number*(p_kernpair+(1-P("EndKernPairs" )))^0*P("EndKernPairs" )
-local function set_1(data,key,a)   data.metadata[lower(key)]=a      end
-local function set_2(data,key,a,b)  data.metadata[lower(key)]={ a,b }  end
-local function set_3(data,key,a,b,c) data.metadata[lower(key)]={ a,b,c } end
-local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName"))/lower)*words/function(data,key,value)
-    data.metadata[key]=value
-  end+fontdata*((P("Weight")+P("Version"))/lower)*name/function(data,key,value)
-    data.metadata[key]=value
-  end+fontdata*P("IsFixedPitch")*name/function(data,pitch)
-    data.metadata.monospaced=toboolean(pitch,true)
-  end+fontdata*P("FontBBox")*Ct(number^4)/function(data,boundingbox)
-    data.metadata.boundingbox=boundingbox
- end+fontdata*((P("CharWidth")+P("CapHeight")+P("XHeight")+P("Descender")+P("Ascender")+P("ItalicAngle"))/lower)*number/function(data,key,value)
-    data.metadata[key]=value
-  end+P("Comment")*spacing*(P(false)+(fontdata*C("DESIGNSIZE")*number*rest)/set_1 
-+(fontdata*C("TFM designsize")*number*rest)/set_1+(fontdata*C("DesignSize")*number*rest)/set_1+(fontdata*C("CODINGSCHEME")*words*rest)/set_1 
-+(fontdata*C("CHECKSUM")*number*words*rest)/set_1 
-+(fontdata*C("SPACE")*number*plus*minus*rest)/set_3 
-+(fontdata*C("QUAD")*number*rest)/set_1 
-+(fontdata*C("EXTRASPACE")*number*rest)/set_1 
-+(fontdata*C("NUM")*number*number*number*rest)/set_3 
-+(fontdata*C("DENOM")*number*number*rest)/set_2 
-+(fontdata*C("SUP")*number*number*number*rest)/set_3 
-+(fontdata*C("SUB")*number*number*rest)/set_2 
-+(fontdata*C("SUPDROP")*number*rest)/set_1 
-+(fontdata*C("SUBDROP")*number*rest)/set_1 
-+(fontdata*C("DELIM")*number*number*rest)/set_2 
-+(fontdata*C("AXISHEIGHT")*number*rest)/set_1 
-  )
-local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
-local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
-local infoparser=(P("StartFontMetrics")*fontdata*name/start )*(p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
-local function read(filename,parser)
-  local afmblob=io.loaddata(filename)
-  if afmblob then
-    local data={
-      resources={
-        filename=resolvers.unresolve(filename),
-        version=afm.version,
-        creator="context mkiv",
-      },
-      properties={
-        hasitalics=false,
-      },
-      goodies={},
-      metadata={
-        filename=file.removesuffix(file.basename(filename))
-      },
-      characters={
-      },
-      descriptions={
-      },
-    }
-    if trace_loading then
-      report_afm("parsing afm file %a",filename)
-    end
-    lpegmatch(parser,afmblob,1,data)
-    return data
-  else
-    if trace_loading then
-      report_afm("no valid afm file %a",filename)
-    end
-    return nil
-  end
-end
-function readers.loadfont(afmname,pfbname)
-  local data=read(resolvers.findfile(afmname),fullparser)
-  if data then
-    if not pfbname or pfbname=="" then
-      pfbname=file.replacesuffix(file.nameonly(afmname),"pfb")
-      pfbname=resolvers.findfile(pfbname)
-    end
-    if pfbname and pfbname~="" then
-      data.resources.filename=resolvers.unresolve(pfbname)
-      get_indexes(data,pfbname)
-    elseif trace_loading then
-      report_afm("no pfb file for %a",afmname)
-    end
-    return data
-  end
-end
-function readers.loadshapes(filename)
-  local fullname=resolvers.findfile(filename) or ""
-  if fullname=="" then
-    return {
-      filename="not found: "..filename,
-      glyphs={}
-    }
-  else
-    return {
-      filename=fullname,
-      format="opentype",
-      glyphs=get_shapes(fullname) or {},
-      units=1000,
-    }
-  end
-end
-function readers.getinfo(filename)
-  local data=read(resolvers.findfile(filename),infoparser)
-  if data then
-    return data.metadata
-  end
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-onr”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-one” 6fbf6b9e219a944cd1ad5933d77cc488] ---
-
-if not modules then modules={} end modules ['font-one']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,resolvers
-local next,type,tonumber,rawget=next,type,tonumber,rawget
-local match,gmatch,lower,gsub,strip,find=string.match,string.gmatch,string.lower,string.gsub,string.strip,string.find
-local char,byte,sub=string.char,string.byte,string.sub
-local abs=math.abs
-local bxor,rshift=bit32.bxor,bit32.rshift
-local P,S,R,Cmt,C,Ct,Cs,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg
-local lpegmatch,patterns=lpeg.match,lpeg.patterns
-local trace_features=false trackers.register("afm.features",function(v) trace_features=v end)
-local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
-local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
-local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
-local report_afm=logs.reporter("fonts","afm loading")
-local setmetatableindex=table.setmetatableindex
-local derivetable=table.derive
-local findbinfile=resolvers.findbinfile
-local definers=fonts.definers
-local readers=fonts.readers
-local constructors=fonts.constructors
-local afm=constructors.handlers.afm
-local pfb=constructors.handlers.pfb
-local otf=fonts.handlers.otf
-local otfreaders=otf.readers
-local otfenhancers=otf.enhancers
-local afmfeatures=constructors.features.afm
-local registerafmfeature=afmfeatures.register
-local afmenhancers=constructors.enhancers.afm
-local registerafmenhancer=afmenhancers.register
-afm.version=1.512 
-afm.cache=containers.define("fonts","one",afm.version,true)
-afm.autoprefixed=true 
-afm.helpdata={} 
-afm.syncspace=true 
-local overloads=fonts.mappings.overloads
-local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes
-function afm.load(filename)
-  filename=resolvers.findfile(filename,'afm') or ""
-  if filename~="" and not fonts.names.ignoredfile(filename) then
-    local name=file.removesuffix(file.basename(filename))
-    local data=containers.read(afm.cache,name)
-    local attr=lfs.attributes(filename)
-    local size,time=attr.size or 0,attr.modification or 0
-    local pfbfile=file.replacesuffix(name,"pfb")
-    local pfbname=resolvers.findfile(pfbfile,"pfb") or ""
-    if pfbname=="" then
-      pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or ""
-    end
-    local pfbsize,pfbtime=0,0
-    if pfbname~="" then
-      local attr=lfs.attributes(pfbname)
-      pfbsize=attr.size or 0
-      pfbtime=attr.modification or 0
-    end
-    if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then
-      report_afm("reading %a",filename)
-      data=afm.readers.loadfont(filename,pfbname)
-      if data then
-        afmenhancers.apply(data,filename)
-        fonts.mappings.addtounicode(data,filename)
-        otfreaders.pack(data)
-        data.size=size
-        data.time=time
-        data.pfbsize=pfbsize
-        data.pfbtime=pfbtime
-        report_afm("saving %a in cache",name)
-        data=containers.write(afm.cache,name,data)
-        data=containers.read(afm.cache,name)
-      end
-    end
-    if data then
-      otfreaders.unpack(data)
-      otfreaders.expand(data) 
-      otfreaders.addunicodetable(data) 
-      otfenhancers.apply(data,filename,data)
-      if applyruntimefixes then
-        applyruntimefixes(filename,data)
-      end
-    end
-    return data
-  end
-end
-local uparser=fonts.mappings.makenameparser() 
-local function enhance_unify_names(data,filename)
-  local unicodevector=fonts.encodings.agl.unicodes 
-  local unicodes={}
-  local names={}
-  local private=constructors.privateoffset
-  local descriptions=data.descriptions
-  for name,blob in next,data.characters do
-    local code=unicodevector[name] 
-    if not code then
-      code=lpegmatch(uparser,name)
-      if type(code)~="number" then
-        code=private
-        private=private+1
-        report_afm("assigning private slot %U for unknown glyph name %a",code,name)
-      end
-    end
-    local index=blob.index
-    unicodes[name]=code
-    names[name]=index
-    blob.name=name
-    descriptions[code]={
-      boundingbox=blob.boundingbox,
-      width=blob.width,
-      kerns=blob.kerns,
-      index=index,
-      name=name,
-    }
-  end
-  for unicode,description in next,descriptions do
-    local kerns=description.kerns
-    if kerns then
-      local krn={}
-      for name,kern in next,kerns do
-        local unicode=unicodes[name]
-        if unicode then
-          krn[unicode]=kern
-        else
-        end
-      end
-      description.kerns=krn
-    end
-  end
-  data.characters=nil
-  local resources=data.resources
-  local filename=resources.filename or file.removesuffix(file.basename(filename))
-  resources.filename=resolvers.unresolve(filename) 
-  resources.unicodes=unicodes 
-  resources.marks={}
-  resources.private=private
-end
-local everywhere={ ["*"]={ ["*"]=true } } 
-local noflags={ false,false,false,false }
-local function enhance_normalize_features(data)
-  local ligatures=setmetatableindex("table")
-  local kerns=setmetatableindex("table")
-  local extrakerns=setmetatableindex("table")
-  for u,c in next,data.descriptions do
-    local l=c.ligatures
-    local k=c.kerns
-    local e=c.extrakerns
-    if l then
-      ligatures[u]=l
-      for u,v in next,l do
-        l[u]={ ligature=v }
-      end
-      c.ligatures=nil
-    end
-    if k then
-      kerns[u]=k
-      for u,v in next,k do
-        k[u]=v 
-      end
-      c.kerns=nil
-    end
-    if e then
-      extrakerns[u]=e
-      for u,v in next,e do
-        e[u]=v 
-      end
-      c.extrakerns=nil
-    end
-  end
-  local features={
-    gpos={},
-    gsub={},
-  }
-  local sequences={
-  }
-  if next(ligatures) then
-    features.gsub.liga=everywhere
-    data.properties.hasligatures=true
-    sequences[#sequences+1]={
-      features={
-        liga=everywhere,
-      },
-      flags=noflags,
-      name="s_s_0",
-      nofsteps=1,
-      order={ "liga" },
-      type="gsub_ligature",
-      steps={
-        {
-          coverage=ligatures,
-        },
-      },
-    }
-  end
-  if next(kerns) then
-    features.gpos.kern=everywhere
-    data.properties.haskerns=true
-    sequences[#sequences+1]={
-      features={
-        kern=everywhere,
-      },
-      flags=noflags,
-      name="p_s_0",
-      nofsteps=1,
-      order={ "kern" },
-      type="gpos_pair",
-      steps={
-        {
-          format="kern",
-          coverage=kerns,
-        },
-      },
-    }
-  end
-  if next(extrakerns) then
-    features.gpos.extrakerns=everywhere
-    data.properties.haskerns=true
-    sequences[#sequences+1]={
-      features={
-        extrakerns=everywhere,
-      },
-      flags=noflags,
-      name="p_s_1",
-      nofsteps=1,
-      order={ "extrakerns" },
-      type="gpos_pair",
-      steps={
-        {
-          format="kern",
-          coverage=extrakerns,
-        },
-      },
-    }
-  end
-  data.resources.features=features
-  data.resources.sequences=sequences
-end
-local function enhance_fix_names(data)
-  for k,v in next,data.descriptions do
-    local n=v.name
-    local r=overloads[n]
-    if r then
-      local name=r.name
-      if trace_indexing then
-        report_afm("renaming characters %a to %a",n,name)
-      end
-      v.name=name
-      v.unicode=r.unicode
-    end
-  end
-end
-local addthem=function(rawdata,ligatures)
-  if ligatures then
-    local descriptions=rawdata.descriptions
-    local resources=rawdata.resources
-    local unicodes=resources.unicodes
-    for ligname,ligdata in next,ligatures do
-      local one=descriptions[unicodes[ligname]]
-      if one then
-        for _,pair in next,ligdata do
-          local two,three=unicodes[pair[1]],unicodes[pair[2]]
-          if two and three then
-            local ol=one.ligatures
-            if ol then
-              if not ol[two] then
-                ol[two]=three
-              end
-            else
-              one.ligatures={ [two]=three }
-            end
-          end
-        end
-      end
-    end
-  end
-end
-local function enhance_add_ligatures(rawdata)
-  addthem(rawdata,afm.helpdata.ligatures)
-end
-local function enhance_add_extra_kerns(rawdata) 
-  local descriptions=rawdata.descriptions
-  local resources=rawdata.resources
-  local unicodes=resources.unicodes
-  local function do_it_left(what)
-    if what then
-      for unicode,description in next,descriptions do
-        local kerns=description.kerns
-        if kerns then
-          local extrakerns
-          for complex,simple in next,what do
-            complex=unicodes[complex]
-            simple=unicodes[simple]
-            if complex and simple then
-              local ks=kerns[simple]
-              if ks and not kerns[complex] then
-                if extrakerns then
-                  extrakerns[complex]=ks
-                else
-                  extrakerns={ [complex]=ks }
-                end
-              end
-            end
-          end
-          if extrakerns then
-            description.extrakerns=extrakerns
-          end
-        end
-      end
-    end
-  end
-  local function do_it_copy(what)
-    if what then
-      for complex,simple in next,what do
-        complex=unicodes[complex]
-        simple=unicodes[simple]
-        if complex and simple then
-          local complexdescription=descriptions[complex]
-          if complexdescription then 
-            local simpledescription=descriptions[complex]
-            if simpledescription then
-              local extrakerns
-              local kerns=simpledescription.kerns
-              if kerns then
-                for unicode,kern in next,kerns do
-                  if extrakerns then
-                    extrakerns[unicode]=kern
-                  else
-                    extrakerns={ [unicode]=kern }
-                  end
-                end
-              end
-              local extrakerns=simpledescription.extrakerns
-              if extrakerns then
-                for unicode,kern in next,extrakerns do
-                  if extrakerns then
-                    extrakerns[unicode]=kern
-                  else
-                    extrakerns={ [unicode]=kern }
-                  end
-                end
-              end
-              if extrakerns then
-                complexdescription.extrakerns=extrakerns
-              end
-            end
-          end
-        end
-      end
-    end
-  end
-  do_it_left(afm.helpdata.leftkerned)
-  do_it_left(afm.helpdata.bothkerned)
-  do_it_copy(afm.helpdata.bothkerned)
-  do_it_copy(afm.helpdata.rightkerned)
-end
-local function adddimensions(data) 
-  if data then
-    for unicode,description in next,data.descriptions do
-      local bb=description.boundingbox
-      if bb then
-        local ht,dp=bb[4],-bb[2]
-        if ht==0 or ht<0 then
-        else
-          description.height=ht
-        end
-        if dp==0 or dp<0 then
-        else
-          description.depth=dp
-        end
-      end
-    end
-  end
-end
-local function copytotfm(data)
-  if data and data.descriptions then
-    local metadata=data.metadata
-    local resources=data.resources
-    local properties=derivetable(data.properties)
-    local descriptions=derivetable(data.descriptions)
-    local goodies=derivetable(data.goodies)
-    local characters={}
-    local parameters={}
-    local unicodes=resources.unicodes
-    for unicode,description in next,data.descriptions do 
-      characters[unicode]={}
-    end
-    local filename=constructors.checkedfilename(resources)
-    local fontname=metadata.fontname or metadata.fullname
-    local fullname=metadata.fullname or metadata.fontname
-    local endash=0x0020 
-    local emdash=0x2014
-    local spacer="space"
-    local spaceunits=500
-    local monospaced=metadata.monospaced
-    local charwidth=metadata.charwidth
-    local italicangle=metadata.italicangle
-    local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight
-    properties.monospaced=monospaced
-    parameters.italicangle=italicangle
-    parameters.charwidth=charwidth
-    parameters.charxheight=charxheight
-    if properties.monospaced then
-      if descriptions[endash] then
-        spaceunits,spacer=descriptions[endash].width,"space"
-      end
-      if not spaceunits and descriptions[emdash] then
-        spaceunits,spacer=descriptions[emdash].width,"emdash"
-      end
-      if not spaceunits and charwidth then
-        spaceunits,spacer=charwidth,"charwidth"
-      end
-    else
-      if descriptions[endash] then
-        spaceunits,spacer=descriptions[endash].width,"space"
-      end
-      if not spaceunits and charwidth then
-        spaceunits,spacer=charwidth,"charwidth"
-      end
-    end
-    spaceunits=tonumber(spaceunits)
-    if spaceunits<200 then
-    end
-    parameters.slant=0
-    parameters.space=spaceunits
-    parameters.space_stretch=500
-    parameters.space_shrink=333
-    parameters.x_height=400
-    parameters.quad=1000
-    if italicangle and italicangle~=0 then
-      parameters.italicangle=italicangle
-      parameters.italicfactor=math.cos(math.rad(90+italicangle))
-      parameters.slant=- math.tan(italicangle*math.pi/180)
-    end
-    if monospaced then
-      parameters.space_stretch=0
-      parameters.space_shrink=0
-    elseif afm.syncspace then
-      parameters.space_stretch=spaceunits/2
-      parameters.space_shrink=spaceunits/3
-    end
-    parameters.extra_space=parameters.space_shrink
-    if charxheight then
-      parameters.x_height=charxheight
-    else
-      local x=0x0078 
-      if x then
-        local x=descriptions[x]
-        if x then
-          parameters.x_height=x.height
-        end
-      end
-    end
-    if metadata.sup then
-      local dummy={ 0,0,0 }
-      parameters[ 1]=metadata.designsize    or 0
-      parameters[ 2]=metadata.checksum     or 0
-      parameters[ 3],
-      parameters[ 4],
-      parameters[ 5]=unpack(metadata.space   or dummy)
-      parameters[ 6]=metadata.quad    or 0
-      parameters[ 7]=metadata.extraspace or 0
-      parameters[ 8],
-      parameters[ 9],
-      parameters[10]=unpack(metadata.num    or dummy)
-      parameters[11],
-      parameters[12]=unpack(metadata.denom   or dummy)
-      parameters[13],
-      parameters[14],
-      parameters[15]=unpack(metadata.sup    or dummy)
-      parameters[16],
-      parameters[17]=unpack(metadata.sub    or dummy)
-      parameters[18]=metadata.supdrop  or 0
-      parameters[19]=metadata.subdrop  or 0
-      parameters[20],
-      parameters[21]=unpack(metadata.delim   or dummy)
-      parameters[22]=metadata.axisheight or 0
-    end
-    parameters.designsize=(metadata.designsize or 10)*65536
-    parameters.ascender=abs(metadata.ascender or 0)
-    parameters.descender=abs(metadata.descender or 0)
-    parameters.units=1000
-    properties.spacer=spacer
-    properties.encodingbytes=2
-    properties.format=fonts.formats[filename] or "type1"
-    properties.filename=filename
-    properties.fontname=fontname
-    properties.fullname=fullname
-    properties.psname=fullname
-    properties.name=filename or fullname or fontname
-    if next(characters) then
-      return {
-        characters=characters,
-        descriptions=descriptions,
-        parameters=parameters,
-        resources=resources,
-        properties=properties,
-        goodies=goodies,
-      }
-    end
-  end
-  return nil
-end
-function afm.setfeatures(tfmdata,features)
-  local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm)
-  if okay then
-    return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm)
-  else
-    return {} 
-  end
-end
-local function addtables(data)
-  local resources=data.resources
-  local lookuptags=resources.lookuptags
-  local unicodes=resources.unicodes
-  if not lookuptags then
-    lookuptags={}
-    resources.lookuptags=lookuptags
-  end
-  setmetatableindex(lookuptags,function(t,k)
-    local v=type(k)=="number" and ("lookup "..k) or k
-    t[k]=v
-    return v
-  end)
-  if not unicodes then
-    unicodes={}
-    resources.unicodes=unicodes
-    setmetatableindex(unicodes,function(t,k)
-      setmetatableindex(unicodes,nil)
-      for u,d in next,data.descriptions do
-        local n=d.name
-        if n then
-          t[n]=u
-        end
-      end
-      return rawget(t,k)
-    end)
-  end
-  constructors.addcoreunicodes(unicodes) 
-end
-local function afmtotfm(specification)
-  local afmname=specification.filename or specification.name
-  if specification.forced=="afm" or specification.format=="afm" then 
-    if trace_loading then
-      report_afm("forcing afm format for %a",afmname)
-    end
-  else
-    local tfmname=findbinfile(afmname,"ofm") or ""
-    if tfmname~="" then
-      if trace_loading then
-        report_afm("fallback from afm to tfm for %a",afmname)
-      end
-      return 
-    end
-  end
-  if afmname~="" then
-    local features=constructors.checkedfeatures("afm",specification.features.normal)
-    specification.features.normal=features
-    constructors.hashinstance(specification,true)
-    specification=definers.resolve(specification) 
-    local cache_id=specification.hash
-    local tfmdata=containers.read(constructors.cache,cache_id) 
-    if not tfmdata then
-      local rawdata=afm.load(afmname)
-      if rawdata and next(rawdata) then
-        addtables(rawdata)
-        adddimensions(rawdata)
-        tfmdata=copytotfm(rawdata)
-        if tfmdata and next(tfmdata) then
-          local shared=tfmdata.shared
-          if not shared then
-            shared={}
-            tfmdata.shared=shared
-          end
-          shared.rawdata=rawdata
-          shared.dynamics={}
-          tfmdata.changed={}
-          shared.features=features
-          shared.processes=afm.setfeatures(tfmdata,features)
-        end
-      elseif trace_loading then
-        report_afm("no (valid) afm file found with name %a",afmname)
-      end
-      tfmdata=containers.write(constructors.cache,cache_id,tfmdata)
-    end
-    return tfmdata
-  end
-end
-local function read_from_afm(specification)
-  local tfmdata=afmtotfm(specification)
-  if tfmdata then
-    tfmdata.properties.name=specification.name
-    tfmdata=constructors.scale(tfmdata,specification)
-    local allfeatures=tfmdata.shared.features or specification.features.normal
-    constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm)
-    fonts.loggers.register(tfmdata,'afm',specification)
-  end
-  return tfmdata
-end
-registerafmfeature {
-  name="mode",
-  description="mode",
-  initializers={
-    base=otf.modeinitializer,
-    node=otf.modeinitializer,
-  }
-}
-registerafmfeature {
-  name="features",
-  description="features",
-  default=true,
-  initializers={
-    node=otf.nodemodeinitializer,
-    base=otf.basemodeinitializer,
-  },
-  processors={
-    node=otf.featuresprocessor,
-  }
-}
-fonts.formats.afm="type1"
-fonts.formats.pfb="type1"
-local function check_afm(specification,fullname)
-  local foundname=findbinfile(fullname,'afm') or "" 
-  if foundname=="" then
-    foundname=fonts.names.getfilename(fullname,"afm") or ""
-  end
-  if foundname=="" and afm.autoprefixed then
-    local encoding,shortname=match(fullname,"^(.-)%-(.*)$") 
-    if encoding and shortname and fonts.encodings.known[encoding] then
-      shortname=findbinfile(shortname,'afm') or "" 
-      if shortname~="" then
-        foundname=shortname
-        if trace_defining then
-          report_afm("stripping encoding prefix from filename %a",afmname)
-        end
-      end
-    end
-  end
-  if foundname~="" then
-    specification.filename=foundname
-    specification.format="afm"
-    return read_from_afm(specification)
-  end
-end
-function readers.afm(specification,method)
-  local fullname=specification.filename or ""
-  local tfmdata=nil
-  if fullname=="" then
-    local forced=specification.forced or ""
-    if forced~="" then
-      tfmdata=check_afm(specification,specification.name.."."..forced)
-    end
-    if not tfmdata then
-      local check_tfm=readers.check_tfm
-      method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm"
-      if method=="tfm" then
-        tfmdata=check_tfm(specification,specification.name)
-      elseif method=="afm" then
-        tfmdata=check_afm(specification,specification.name)
-      elseif method=="tfm or afm" then
-        tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name)
-      else 
-        tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name)
-      end
-    end
-  else
-    tfmdata=check_afm(specification,fullname)
-  end
-  return tfmdata
-end
-function readers.pfb(specification,method) 
-  local original=specification.specification
-  if trace_defining then
-    report_afm("using afm reader for %a",original)
-  end
-  specification.forced="afm"
-  local function swap(name)
-    local value=specification[swap]
-    if value then
-      specification[swap]=gsub("%.pfb",".afm",1)
-    end
-  end
-  swap("filename")
-  swap("fullname")
-  swap("forcedname")
-  swap("specification")
-  return readers.afm(specification,method)
-end
-registerafmenhancer("unify names",enhance_unify_names)
-registerafmenhancer("add ligatures",enhance_add_ligatures)
-registerafmenhancer("add extra kerns",enhance_add_extra_kerns)
-registerafmenhancer("normalize features",enhance_normalize_features)
-registerafmenhancer("check extra features",otfenhancers.enhance)
-registerafmenhancer("fix names",enhance_fix_names)
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-one”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-afk” b36a76ceb835f41f8c05b471000ddc14] ---
-
-if not modules then modules={} end modules ['font-afk']={
-  version=1.001,
-  comment="companion to font-afm.lua",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files",
-  dataonly=true,
-}
-local allocate=utilities.storage.allocate
-fonts.handlers.afm.helpdata={
-  ligatures=allocate { 
-    ['f']={ 
-      { 'f','ff' },
-      { 'i','fi' },
-      { 'l','fl' },
-    },
-    ['ff']={
-      { 'i','ffi' }
-    },
-    ['fi']={
-      { 'i','fii' }
-    },
-    ['fl']={
-      { 'i','fli' }
-    },
-    ['s']={
-      { 't','st' }
-    },
-    ['i']={
-      { 'j','ij' }
-    },
-  },
-  texligatures=allocate {
-    ['quoteleft']={
-      { 'quoteleft','quotedblleft' }
-    },
-    ['quoteright']={
-      { 'quoteright','quotedblright' }
-    },
-    ['hyphen']={
-      { 'hyphen','endash' }
-    },
-    ['endash']={
-      { 'hyphen','emdash' }
-    }
-  },
-  leftkerned=allocate {
-    AEligature="A",aeligature="a",
-    OEligature="O",oeligature="o",
-    IJligature="I",ijligature="i",
-    AE="A",ae="a",
-    OE="O",oe="o",
-    IJ="I",ij="i",
-    Ssharp="S",ssharp="s",
-  },
-  rightkerned=allocate {
-    AEligature="E",aeligature="e",
-    OEligature="E",oeligature="e",
-    IJligature="J",ijligature="j",
-    AE="E",ae="e",
-    OE="E",oe="e",
-    IJ="J",ij="j",
-    Ssharp="S",ssharp="s",
-  },
-  bothkerned=allocate {
-    Acircumflex="A",acircumflex="a",
-    Ccircumflex="C",ccircumflex="c",
-    Ecircumflex="E",ecircumflex="e",
-    Gcircumflex="G",gcircumflex="g",
-    Hcircumflex="H",hcircumflex="h",
-    Icircumflex="I",icircumflex="i",
-    Jcircumflex="J",jcircumflex="j",
-    Ocircumflex="O",ocircumflex="o",
-    Scircumflex="S",scircumflex="s",
-    Ucircumflex="U",ucircumflex="u",
-    Wcircumflex="W",wcircumflex="w",
-    Ycircumflex="Y",ycircumflex="y",
-    Agrave="A",agrave="a",
-    Egrave="E",egrave="e",
-    Igrave="I",igrave="i",
-    Ograve="O",ograve="o",
-    Ugrave="U",ugrave="u",
-    Ygrave="Y",ygrave="y",
-    Atilde="A",atilde="a",
-    Itilde="I",itilde="i",
-    Otilde="O",otilde="o",
-    Utilde="U",utilde="u",
-    Ntilde="N",ntilde="n",
-    Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a",
-    Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e",
-    Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i",
-    Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o",
-    Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u",
-    Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y",
-    Aacute="A",aacute="a",
-    Cacute="C",cacute="c",
-    Eacute="E",eacute="e",
-    Iacute="I",iacute="i",
-    Lacute="L",lacute="l",
-    Nacute="N",nacute="n",
-    Oacute="O",oacute="o",
-    Racute="R",racute="r",
-    Sacute="S",sacute="s",
-    Uacute="U",uacute="u",
-    Yacute="Y",yacute="y",
-    Zacute="Z",zacute="z",
-    Dstroke="D",dstroke="d",
-    Hstroke="H",hstroke="h",
-    Tstroke="T",tstroke="t",
-    Cdotaccent="C",cdotaccent="c",
-    Edotaccent="E",edotaccent="e",
-    Gdotaccent="G",gdotaccent="g",
-    Idotaccent="I",idotaccent="i",
-    Zdotaccent="Z",zdotaccent="z",
-    Amacron="A",amacron="a",
-    Emacron="E",emacron="e",
-    Imacron="I",imacron="i",
-    Omacron="O",omacron="o",
-    Umacron="U",umacron="u",
-    Ccedilla="C",ccedilla="c",
-    Kcedilla="K",kcedilla="k",
-    Lcedilla="L",lcedilla="l",
-    Ncedilla="N",ncedilla="n",
-    Rcedilla="R",rcedilla="r",
-    Scedilla="S",scedilla="s",
-    Tcedilla="T",tcedilla="t",
-    Ohungarumlaut="O",ohungarumlaut="o",
-    Uhungarumlaut="U",uhungarumlaut="u",
-    Aogonek="A",aogonek="a",
-    Eogonek="E",eogonek="e",
-    Iogonek="I",iogonek="i",
-    Uogonek="U",uogonek="u",
-    Aring="A",aring="a",
-    Uring="U",uring="u",
-    Abreve="A",abreve="a",
-    Ebreve="E",ebreve="e",
-    Gbreve="G",gbreve="g",
-    Ibreve="I",ibreve="i",
-    Obreve="O",obreve="o",
-    Ubreve="U",ubreve="u",
-    Ccaron="C",ccaron="c",
-    Dcaron="D",dcaron="d",
-    Ecaron="E",ecaron="e",
-    Lcaron="L",lcaron="l",
-    Ncaron="N",ncaron="n",
-    Rcaron="R",rcaron="r",
-    Scaron="S",scaron="s",
-    Tcaron="T",tcaron="t",
-    Zcaron="Z",zcaron="z",
-    dotlessI="I",dotlessi="i",
-    dotlessJ="J",dotlessj="j",
-    AEligature="AE",aeligature="ae",AE="AE",ae="ae",
-    OEligature="OE",oeligature="oe",OE="OE",oe="oe",
-    IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij",
-    Lstroke="L",lstroke="l",Lslash="L",lslash="l",
-    Ostroke="O",ostroke="o",Oslash="O",oslash="o",
-    Ssharp="SS",ssharp="ss",
-    Aumlaut="A",aumlaut="a",
-    Eumlaut="E",eumlaut="e",
-    Iumlaut="I",iumlaut="i",
-    Oumlaut="O",oumlaut="o",
-    Uumlaut="U",uumlaut="u",
-  }
-}
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-afk”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-tfm” 3d813578dbf6c447e4b859c2bf0618f7] ---
-
-if not modules then modules={} end modules ['font-tfm']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local next,type=next,type
-local match,format=string.match,string.format
-local concat,sortedhash=table.concat,table.sortedhash
-local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
-local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end)
-local report_defining=logs.reporter("fonts","defining")
-local report_tfm=logs.reporter("fonts","tfm loading")
-local findbinfile=resolvers.findbinfile
-local setmetatableindex=table.setmetatableindex
-local fonts=fonts
-local handlers=fonts.handlers
-local readers=fonts.readers
-local constructors=fonts.constructors
-local encodings=fonts.encodings
-local tfm=constructors.handlers.tfm
-tfm.version=1.000
-tfm.maxnestingdepth=5
-tfm.maxnestingsize=65536*1024
-local otf=fonts.handlers.otf
-local otfenhancers=otf.enhancers
-local tfmfeatures=constructors.features.tfm
-local registertfmfeature=tfmfeatures.register
-local tfmenhancers=constructors.enhancers.tfm
-local registertfmenhancer=tfmenhancers.register
-constructors.resolvevirtualtoo=false 
-fonts.formats.tfm="type1" 
-fonts.formats.ofm="type1"
-function tfm.setfeatures(tfmdata,features)
-  local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm)
-  if okay then
-    return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm)
-  else
-    return {} 
-  end
-end
-local depth={}
-local function read_from_tfm(specification)
-  local filename=specification.filename
-  local size=specification.size
-  depth[filename]=(depth[filename] or 0)+1
-  if trace_defining then
-    report_defining("loading tfm file %a at size %s",filename,size)
-  end
-  local tfmdata=font.read_tfm(filename,size) 
-  if tfmdata then
-    local features=specification.features and specification.features.normal or {}
-    local features=constructors.checkedfeatures("tfm",features)
-    specification.features.normal=features
-    local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification)
-    if newtfmdata then
-       tfmdata=newtfmdata
-    end
-    local resources=tfmdata.resources or {}
-    local properties=tfmdata.properties or {}
-    local parameters=tfmdata.parameters or {}
-    local shared=tfmdata.shared   or {}
-    shared.features=features
-    shared.resources=resources
-    properties.name=tfmdata.name      
-    properties.fontname=tfmdata.fontname    
-    properties.psname=tfmdata.psname     
-    properties.fullname=tfmdata.fullname    
-    properties.filename=specification.filename 
-    properties.format=fonts.formats.tfm
-    tfmdata.properties=properties
-    tfmdata.resources=resources
-    tfmdata.parameters=parameters
-    tfmdata.shared=shared
-    shared.rawdata={ resources=resources }
-    shared.features=features
-    if newtfmdata then
-      if not resources.marks then
-        resources.marks={}
-      end
-      if not resources.sequences then
-        resources.sequences={}
-      end
-      if not resources.features then
-        resources.features={
-          gsub={},
-          gpos={},
-        }
-      end
-      if not tfmdata.changed then
-        tfmdata.changed={}
-      end
-      if not tfmdata.descriptions then
-        tfmdata.descriptions=tfmdata.characters
-      end
-      otf.readers.addunicodetable(tfmdata)
-      tfmenhancers.apply(tfmdata,filename)
-      constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm)
-      otf.readers.unifymissing(tfmdata)
-      fonts.mappings.addtounicode(tfmdata,filename)
-      tfmdata.tounicode=1
-      local tounicode=fonts.mappings.tounicode
-      for unicode,v in next,tfmdata.characters do
-        local u=v.unicode
-        if u then
-          v.tounicode=tounicode(u)
-        end
-      end
-      if tfmdata.usedbitmap then
-        tfm.addtounicode(tfmdata)
-      end
-    end
-    shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil
-    parameters.factor=1 
-    parameters.size=size
-    parameters.slant=parameters.slant     or parameters[1] or 0
-    parameters.space=parameters.space     or parameters[2] or 0
-    parameters.space_stretch=parameters.space_stretch or parameters[3] or 0
-    parameters.space_shrink=parameters.space_shrink  or parameters[4] or 0
-    parameters.x_height=parameters.x_height    or parameters[5] or 0
-    parameters.quad=parameters.quad      or parameters[6] or 0
-    parameters.extra_space=parameters.extra_space  or parameters[7] or 0
-    constructors.enhanceparameters(parameters)
-    if newtfmdata then
-    elseif constructors.resolvevirtualtoo then
-      fonts.loggers.register(tfmdata,file.suffix(filename),specification) 
-      local vfname=findbinfile(specification.name,'ovf')
-      if vfname and vfname~="" then
-        local vfdata=font.read_vf(vfname,size) 
-        if vfdata then
-          local chars=tfmdata.characters
-          for k,v in next,vfdata.characters do
-            chars[k].commands=v.commands
-          end
-          properties.virtualized=true
-          tfmdata.fonts=vfdata.fonts
-          tfmdata.type="virtual" 
-          local fontlist=vfdata.fonts
-          local name=file.nameonly(filename)
-          for i=1,#fontlist do
-            local n=fontlist[i].name
-            local s=fontlist[i].size
-            local d=depth[filename]
-            s=constructors.scaled(s,vfdata.designsize)
-            if d>tfm.maxnestingdepth then
-              report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth)
-              fontlist[i]={ id=0 }
-            elseif (d>1) and (s>tfm.maxnestingsize) then
-              report_defining("virtual font %a exceeds size %s",n,s)
-              fontlist[i]={ id=0 }
-            else
-              local t,id=fonts.constructors.readanddefine(n,s)
-              fontlist[i]={ id=id }
-            end
-          end
-        end
-      end
-    end
-    properties.haskerns=true
-    properties.hasligatures=true
-    resources.unicodes={}
-    resources.lookuptags={}
-    depth[filename]=depth[filename]-1
-    return tfmdata
-  else
-    depth[filename]=depth[filename]-1
-  end
-end
-local function check_tfm(specification,fullname) 
-  local foundname=findbinfile(fullname,'tfm') or ""
-  if foundname=="" then
-    foundname=findbinfile(fullname,'ofm') or "" 
-  end
-  if foundname=="" then
-    foundname=fonts.names.getfilename(fullname,"tfm") or ""
-  end
-  if foundname~="" then
-    specification.filename=foundname
-    specification.format="ofm"
-    return read_from_tfm(specification)
-  elseif trace_defining then
-    report_defining("loading tfm with name %a fails",specification.name)
-  end
-end
-readers.check_tfm=check_tfm
-function readers.tfm(specification)
-  local fullname=specification.filename or ""
-  if fullname=="" then
-    local forced=specification.forced or ""
-    if forced~="" then
-      fullname=specification.name.."."..forced
-    else
-      fullname=specification.name
-    end
-  end
-  return check_tfm(specification,fullname)
-end
-readers.ofm=readers.tfm
-do
-  local outfiles={}
-  local tfmcache=table.setmetatableindex(function(t,tfmdata)
-    local id=font.define(tfmdata)
-    t[tfmdata]=id
-    return id
-  end)
-  local encdone=table.setmetatableindex("table")
-  function tfm.reencode(tfmdata,specification)
-    local features=specification.features
-    if not features then
-      return
-    end
-    local features=features.normal
-    if not features then
-      return
-    end
-    local tfmfile=file.basename(tfmdata.name)
-    local encfile=features.reencode 
-    local pfbfile=features.pfbfile 
-    local bitmap=features.bitmap  
-    if not encfile then
-      return
-    end
-    local pfbfile=outfiles[tfmfile]
-    if pfbfile==nil then
-      if bitmap then
-        pfbfile=false
-      elseif type(pfbfile)~="string" then
-        pfbfile=tfmfile
-      end
-      if type(pfbfile)=="string" then
-        pfbfile=file.addsuffix(pfbfile,"pfb")
-        report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile)
-      else
-        report_tfm("using bitmap shapes for %a",tfmfile)
-        pfbfile=false 
-      end
-      outfiles[tfmfile]=pfbfile
-    end
-    local encoding=false
-    local vector=false
-    if type(pfbfile)=="string" then
-      local pfb=fonts.constructors.handlers.pfb
-      if pfb and pfb.loadvector then
-        local v,e=pfb.loadvector(pfbfile)
-        if v then
-          vector=v
-        end
-        if e then
-          encoding=e
-        end
-      end
-    end
-    if type(encfile)=="string" and encfile~="auto" then
-      encoding=fonts.encodings.load(file.addsuffix(encfile,"enc"))
-      if encoding then
-        encoding=encoding.vector
-      end
-    end
-    if not encoding then
-      report_tfm("bad encoding for %a, quitting",tfmfile)
-      return
-    end
-    local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes
-    local virtualid=tfmcache[tfmdata]
-    local tfmdata=table.copy(tfmdata) 
-    local characters={}
-    local originals=tfmdata.characters
-    local indices={}
-    local parentfont={ "font",1 }
-    local private=fonts.constructors.privateoffset
-    local reported=encdone[tfmfile][encfile]
-    local backmap=vector and table.swapped(vector)
-    local done={} 
-    for index,name in sortedhash(encoding) do 
-      local unicode=unicoding[name]
-      local original=originals[index]
-      if original then
-        if unicode then
-          original.unicode=unicode
-        else
-          unicode=private
-          private=private+1
-          if not reported then
-            report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode)
-          end
-        end
-        characters[unicode]=original
-        indices[index]=unicode
-        original.name=name 
-        if backmap then
-          original.index=backmap[name]
-        else 
-          original.commands={ parentfont,{ "char",index } }
-          original.oindex=index
-        end
-        done[name]=true
-      elseif not done[name] then
-        report_tfm("bad index %a in font %a with name %a",index,tfmfile,name)
-      end
-    end
-    encdone[tfmfile][encfile]=true
-    for k,v in next,characters do
-      local kerns=v.kerns
-      if kerns then
-        local t={}
-        for k,v in next,kerns do
-          local i=indices[k]
-          if i then
-            t[i]=v
-          end
-        end
-        v.kerns=next(t) and t or nil
-      end
-      local ligatures=v.ligatures
-      if ligatures then
-        local t={}
-        for k,v in next,ligatures do
-          local i=indices[k]
-          if i then
-            t[i]=v
-            v.char=indices[v.char]
-          end
-        end
-        v.ligatures=next(t) and t or nil
-      end
-    end
-    tfmdata.fonts={ { id=virtualid } }
-    tfmdata.characters=characters
-    tfmdata.fullname=tfmdata.fullname or tfmdata.name
-    tfmdata.psname=file.nameonly(pfbfile or tfmdata.name)
-    tfmdata.filename=pfbfile
-    tfmdata.encodingbytes=2
-    tfmdata.format="type1"
-    tfmdata.tounicode=1
-    tfmdata.embedding="subset"
-    tfmdata.usedbitmap=bitmap and virtualid
-    return tfmdata
-  end
-end
-do
-  local template=[[
-/CIDInit /ProcSet findresource begin
-  12 dict begin
-  begincmap
-    /CIDSystemInfo << /Registry (TeX) /Ordering (bitmap-%s) /Supplement 0 >> def
-    /CMapName /TeX-bitmap-%s def
-    /CMapType 2 def
-    1 begincodespacerange
-      <00> <FF>
-    endcodespacerange
-    %s beginbfchar
-%s
-    endbfchar
-  endcmap
-CMapName currentdict /CMap defineresource pop end
-end
-end
-]]
-  local flushstreamobject=lpdf and lpdf.flushstreamobject
-  local setfontattributes=pdf.setfontattributes
-  if not flushstreamobject then
-    flushstreamobject=function(data)
-      return pdf.obj {
-        immediate=true,
-        type="stream",
-        string=data,
-      }
-    end
-  end
-  if not setfontattributes then
-    setfontattributes=function(id,data)
-      print(format("your luatex is too old so no tounicode bitmap font%i",id))
-    end
-  end
-  function tfm.addtounicode(tfmdata)
-    local id=tfmdata.usedbitmap
-    local map={}
-    local char={} 
-    for k,v in next,tfmdata.characters do
-      local index=v.oindex
-      local tounicode=v.tounicode
-      if index and tounicode then
-        map[index]=tounicode
-      end
-    end
-    for k,v in sortedhash(map) do
-      char[#char+1]=format("<%02X> <%s>",k,v)
-    end
-    char=concat(char,"\n")
-    local stream=format(template,id,id,#char,char)
-    local reference=flushstreamobject(stream,nil,true)
-    setfontattributes(id,format("/ToUnicode %i 0 R",reference))
-  end
-end
-do
-  local everywhere={ ["*"]={ ["*"]=true } } 
-  local noflags={ false,false,false,false }
-  local function enhance_normalize_features(data)
-    local ligatures=setmetatableindex("table")
-    local kerns=setmetatableindex("table")
-    local characters=data.characters
-    for u,c in next,characters do
-      local l=c.ligatures
-      local k=c.kerns
-      if l then
-        ligatures[u]=l
-        for u,v in next,l do
-          l[u]={ ligature=v.char }
-        end
-        c.ligatures=nil
-      end
-      if k then
-        kerns[u]=k
-        for u,v in next,k do
-          k[u]=v 
-        end
-        c.kerns=nil
-      end
-    end
-    for u,l in next,ligatures do
-      for k,v in next,l do
-        local vl=v.ligature
-        local dl=ligatures[vl]
-        if dl then
-          for kk,vv in next,dl do
-            v[kk]=vv 
-          end
-        end
-      end
-    end
-    local features={
-      gpos={},
-      gsub={},
-    }
-    local sequences={
-    }
-    if next(ligatures) then
-      features.gsub.liga=everywhere
-      data.properties.hasligatures=true
-      sequences[#sequences+1]={
-        features={
-          liga=everywhere,
-        },
-        flags=noflags,
-        name="s_s_0",
-        nofsteps=1,
-        order={ "liga" },
-        type="gsub_ligature",
-        steps={
-          {
-            coverage=ligatures,
-          },
-        },
-      }
-    end
-    if next(kerns) then
-      features.gpos.kern=everywhere
-      data.properties.haskerns=true
-      sequences[#sequences+1]={
-        features={
-          kern=everywhere,
-        },
-        flags=noflags,
-        name="p_s_0",
-        nofsteps=1,
-        order={ "kern" },
-        type="gpos_pair",
-        steps={
-          {
-            format="kern",
-            coverage=kerns,
-          },
-        },
-      }
-    end
-    data.resources.features=features
-    data.resources.sequences=sequences
-    data.shared.resources=data.shared.resources or resources
-  end
-  registertfmenhancer("normalize features",enhance_normalize_features)
-  registertfmenhancer("check extra features",otfenhancers.enhance)
-end
-registertfmfeature {
-  name="mode",
-  description="mode",
-  initializers={
-    base=otf.modeinitializer,
-    node=otf.modeinitializer,
-  }
-}
-registertfmfeature {
-  name="features",
-  description="features",
-  default=true,
-  initializers={
-    base=otf.basemodeinitializer,
-    node=otf.nodemodeinitializer,
-  },
-  processors={
-    node=otf.featuresprocessor,
-  }
-}
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-tfm”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-lua” 1fbfdf7b689b2bdfd0e3bb9bf74ce136] ---
-
-if not modules then modules={} end modules ['font-lua']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
-local report_lua=logs.reporter("fonts","lua loading")
-local fonts=fonts
-local readers=fonts.readers
-fonts.formats.lua="lua"
-local function check_lua(specification,fullname)
-  local fullname=resolvers.findfile(fullname) or ""
-  if fullname~="" then
-    local loader=loadfile(fullname)
-    loader=loader and loader()
-    return loader and loader(specification)
-  end
-end
-readers.check_lua=check_lua
-function readers.lua(specification)
-  local original=specification.specification
-  if trace_defining then
-    report_lua("using lua reader for %a",original)
-  end
-  local fullname=specification.filename or ""
-  if fullname=="" then
-    local forced=specification.forced or ""
-    if forced~="" then
-      fullname=specification.name.."."..forced
-    else
-      fullname=specification.name
-    end
-  end
-  return check_lua(specification,fullname)
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-lua”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-def” 49fa2b50d8d2a1bb70b08b72f858ecd0] ---
-
-if not modules then modules={} end modules ['font-def']={
-  version=1.001,
-  comment="companion to font-ini.mkiv",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-local lower,gsub=string.lower,string.gsub
-local tostring,next=tostring,next
-local lpegmatch=lpeg.match
-local suffixonly,removesuffix=file.suffix,file.removesuffix
-local formatters=string.formatters
-local allocate=utilities.storage.allocate
-local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end)
-local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end)
-trackers.register("fonts.loading","fonts.defining","otf.loading","afm.loading","tfm.loading")
-trackers.register("fonts.all","fonts.*","otf.*","afm.*","tfm.*")
-local report_defining=logs.reporter("fonts","defining")
-local fonts=fonts
-local fontdata=fonts.hashes.identifiers
-local readers=fonts.readers
-local definers=fonts.definers
-local specifiers=fonts.specifiers
-local constructors=fonts.constructors
-local fontgoodies=fonts.goodies
-readers.sequence=allocate { 'otf','ttf','afm','tfm','lua' } 
-local variants=allocate()
-specifiers.variants=variants
-definers.methods=definers.methods or {}
-local internalized=allocate() 
-local lastdefined=nil 
-local loadedfonts=constructors.loadedfonts
-local designsizes=constructors.designsizes
-local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end
-local splitter,splitspecifiers=nil,"" 
-local P,C,S,Cc=lpeg.P,lpeg.C,lpeg.S,lpeg.Cc
-local left=P("(")
-local right=P(")")
-local colon=P(":")
-local space=P(" ")
-definers.defaultlookup="file"
-local prefixpattern=P(false)
-local function addspecifier(symbol)
-  splitspecifiers=splitspecifiers..symbol
-  local method=S(splitspecifiers)
-  local lookup=C(prefixpattern)*colon
-  local sub=left*C(P(1-left-right-method)^1)*right
-  local specification=C(method)*C(P(1)^1)
-  local name=C((1-sub-specification)^1)
-  splitter=P((lookup+Cc(""))*name*(sub+Cc(""))*(specification+Cc("")))
-end
-local function addlookup(str,default)
-  prefixpattern=prefixpattern+P(str)
-end
-definers.addlookup=addlookup
-addlookup("file")
-addlookup("name")
-addlookup("spec")
-local function getspecification(str)
-  return lpegmatch(splitter,str or "") 
-end
-definers.getspecification=getspecification
-function definers.registersplit(symbol,action,verbosename)
-  addspecifier(symbol)
-  variants[symbol]=action
-  if verbosename then
-    variants[verbosename]=action
-  end
-end
-local function makespecification(specification,lookup,name,sub,method,detail,size)
-  size=size or 655360
-  if not lookup or lookup=="" then
-    lookup=definers.defaultlookup
-  end
-  if trace_defining then
-    report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a",
-      specification,lookup,name,sub,method,detail)
-  end
-  local t={
-    lookup=lookup,
-    specification=specification,
-    size=size,
-    name=name,
-    sub=sub,
-    method=method,
-    detail=detail,
-    resolved="",
-    forced="",
-    features={},
-  }
-  return t
-end
-definers.makespecification=makespecification
-function definers.analyze(specification,size)
-  local lookup,name,sub,method,detail=getspecification(specification or "")
-  return makespecification(specification,lookup,name,sub,method,detail,size)
-end
-definers.resolvers=definers.resolvers or {}
-local resolvers=definers.resolvers
-function resolvers.file(specification)
-  local name=resolvefile(specification.name) 
-  local suffix=lower(suffixonly(name))
-  if fonts.formats[suffix] then
-    specification.forced=suffix
-    specification.forcedname=name
-    specification.name=removesuffix(name)
-  else
-    specification.name=name 
-  end
-end
-function resolvers.name(specification)
-  local resolve=fonts.names.resolve
-  if resolve then
-    local resolved,sub,subindex=resolve(specification.name,specification.sub,specification) 
-    if resolved then
-      specification.resolved=resolved
-      specification.sub=sub
-      specification.subindex=subindex
-      local suffix=lower(suffixonly(resolved))
-      if fonts.formats[suffix] then
-        specification.forced=suffix
-        specification.forcedname=resolved
-        specification.name=removesuffix(resolved)
-      else
-        specification.name=resolved
-      end
-    end
-  else
-    resolvers.file(specification)
-  end
-end
-function resolvers.spec(specification)
-  local resolvespec=fonts.names.resolvespec
-  if resolvespec then
-    local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification) 
-    if resolved then
-      specification.resolved=resolved
-      specification.sub=sub
-      specification.subindex=subindex
-      specification.forced=lower(suffixonly(resolved))
-      specification.forcedname=resolved
-      specification.name=removesuffix(resolved)
-    end
-  else
-    resolvers.name(specification)
-  end
-end
-function definers.resolve(specification)
-  if not specification.resolved or specification.resolved=="" then 
-    local r=resolvers[specification.lookup]
-    if r then
-      r(specification)
-    end
-  end
-  if specification.forced=="" then
-    specification.forced=nil
-    specification.forcedname=nil
-  end
-  specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification))
-  if specification.sub and specification.sub~="" then
-    specification.hash=specification.sub..' @ '..specification.hash
-  end
-  return specification
-end
-function definers.applypostprocessors(tfmdata)
-  local postprocessors=tfmdata.postprocessors
-  if postprocessors then
-    local properties=tfmdata.properties
-    for i=1,#postprocessors do
-      local extrahash=postprocessors[i](tfmdata) 
-      if type(extrahash)=="string" and extrahash~="" then
-        extrahash=gsub(lower(extrahash),"[^a-z]","-")
-        properties.fullname=formatters["%s-%s"](properties.fullname,extrahash)
-      end
-    end
-  end
-  return tfmdata
-end
-local function checkembedding(tfmdata)
-  local properties=tfmdata.properties
-  local embedding
-  if directive_embedall then
-    embedding="full"
-  elseif properties and properties.filename and constructors.dontembed[properties.filename] then
-    embedding="no"
-  else
-    embedding="subset"
-  end
-  if properties then
-    properties.embedding=embedding
-  else
-    tfmdata.properties={ embedding=embedding }
-  end
-  tfmdata.embedding=embedding
-end
-function definers.loadfont(specification)
-  local hash=constructors.hashinstance(specification)
-  local tfmdata=loadedfonts[hash] 
-  if not tfmdata then
-    local forced=specification.forced or ""
-    if forced~="" then
-      local reader=readers[lower(forced)] 
-      tfmdata=reader and reader(specification)
-      if not tfmdata then
-        report_defining("forced type %a of %a not found",forced,specification.name)
-      end
-    else
-      local sequence=readers.sequence 
-      for s=1,#sequence do
-        local reader=sequence[s]
-        if readers[reader] then 
-          if trace_defining then
-            report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename)
-          end
-          tfmdata=readers[reader](specification)
-          if tfmdata then
-            break
-          else
-            specification.filename=nil
-          end
-        end
-      end
-    end
-    if tfmdata then
-      tfmdata=definers.applypostprocessors(tfmdata)
-      checkembedding(tfmdata) 
-      loadedfonts[hash]=tfmdata
-      designsizes[specification.hash]=tfmdata.parameters.designsize
-    end
-  end
-  if not tfmdata then
-    report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup)
-  end
-  return tfmdata
-end
-function constructors.checkvirtualids()
-end
-function constructors.readanddefine(name,size) 
-  local specification=definers.analyze(name,size)
-  local method=specification.method
-  if method and variants[method] then
-    specification=variants[method](specification)
-  end
-  specification=definers.resolve(specification)
-  local hash=constructors.hashinstance(specification)
-  local id=definers.registered(hash)
-  if not id then
-    local tfmdata=definers.loadfont(specification)
-    if tfmdata then
-      tfmdata.properties.hash=hash
-      constructors.checkvirtualids(tfmdata) 
-      id=font.define(tfmdata)
-      definers.register(tfmdata,id)
-    else
-      id=0 
-    end
-  end
-  return fontdata[id],id
-end
-function definers.current() 
-  return lastdefined
-end
-function definers.registered(hash)
-  local id=internalized[hash]
-  return id,id and fontdata[id]
-end
-function definers.register(tfmdata,id)
-  if tfmdata and id then
-    local hash=tfmdata.properties.hash
-    if not hash then
-      report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?")
-    elseif not internalized[hash] then
-      internalized[hash]=id
-      if trace_defining then
-        report_defining("registering font, id %s, hash %a",id,hash)
-      end
-      fontdata[id]=tfmdata
-    end
-  end
-end
-function definers.read(specification,size,id) 
-  statistics.starttiming(fonts)
-  if type(specification)=="string" then
-    specification=definers.analyze(specification,size)
-  end
-  local method=specification.method
-  if method and variants[method] then
-    specification=variants[method](specification)
-  end
-  specification=definers.resolve(specification)
-  local hash=constructors.hashinstance(specification)
-  local tfmdata=definers.registered(hash) 
-  if tfmdata then
-    if trace_defining then
-      report_defining("already hashed: %s",hash)
-    end
-  else
-    tfmdata=definers.loadfont(specification) 
-    if tfmdata then
-      if trace_defining then
-        report_defining("loaded and hashed: %s",hash)
-      end
-      tfmdata.properties.hash=hash
-      if id then
-        definers.register(tfmdata,id)
-      end
-    else
-      if trace_defining then
-        report_defining("not loaded and hashed: %s",hash)
-      end
-    end
-  end
-  lastdefined=tfmdata or id 
-  if not tfmdata then 
-    report_defining("unknown font %a, loading aborted",specification.name)
-  elseif trace_defining and type(tfmdata)=="table" then
-    local properties=tfmdata.properties or {}
-    local parameters=tfmdata.parameters or {}
-    report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a",
-      properties.format or "unknown",id,properties.name,parameters.size,properties.encodingbytes,
-      properties.encodingname,properties.fullname,file.basename(properties.filename))
-  end
-  statistics.stoptiming(fonts)
-  return tfmdata
-end
-function font.getfont(id)
-  return fontdata[id] 
-end
-callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)")
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-def”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “fonts-ext” aff3846f4c1f15de0a9f4fd7081e0c68] ---
-
-if not modules then modules={} end modules ['luatex-fonts-ext']={
-  version=1.001,
-  comment="companion to luatex-*.tex",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-if context then
-  texio.write_nl("fatal error: this module is not for context")
-  os.exit()
-end
-local fonts=fonts
-local otffeatures=fonts.constructors.features.otf
-local function initializeitlc(tfmdata,value)
-  if value then
-    local parameters=tfmdata.parameters
-    local italicangle=parameters.italicangle
-    if italicangle and italicangle~=0 then
-      local properties=tfmdata.properties
-      local factor=tonumber(value) or 1
-      properties.hasitalics=true
-      properties.autoitalicamount=factor*(parameters.uwidth or 40)/2
-    end
-  end
-end
-otffeatures.register {
-  name="itlc",
-  description="italic correction",
-  initializers={
-    base=initializeitlc,
-    node=initializeitlc,
-  }
-}
-local function initializeslant(tfmdata,value)
-  value=tonumber(value)
-  if not value then
-    value=0
-  elseif value>1 then
-    value=1
-  elseif value<-1 then
-    value=-1
-  end
-  tfmdata.parameters.slantfactor=value
-end
-otffeatures.register {
-  name="slant",
-  description="slant glyphs",
-  initializers={
-    base=initializeslant,
-    node=initializeslant,
-  }
-}
-local function initializeextend(tfmdata,value)
-  value=tonumber(value)
-  if not value then
-    value=0
-  elseif value>10 then
-    value=10
-  elseif value<-10 then
-    value=-10
-  end
-  tfmdata.parameters.extendfactor=value
-end
-otffeatures.register {
-  name="extend",
-  description="scale glyphs horizontally",
-  initializers={
-    base=initializeextend,
-    node=initializeextend,
-  }
-}
-fonts.protrusions=fonts.protrusions    or {}
-fonts.protrusions.setups=fonts.protrusions.setups or {}
-local setups=fonts.protrusions.setups
-local function initializeprotrusion(tfmdata,value)
-  if value then
-    local setup=setups[value]
-    if setup then
-      local factor,left,right=setup.factor or 1,setup.left or 1,setup.right or 1
-      local emwidth=tfmdata.parameters.quad
-      tfmdata.parameters.protrusion={
-        auto=true,
-      }
-      for i,chr in next,tfmdata.characters do
-        local v,pl,pr=setup[i],nil,nil
-        if v then
-          pl,pr=v[1],v[2]
-        end
-        if pl and pl~=0 then chr.left_protruding=left*pl*factor end
-        if pr and pr~=0 then chr.right_protruding=right*pr*factor end
-      end
-    end
-  end
-end
-otffeatures.register {
-  name="protrusion",
-  description="shift characters into the left and or right margin",
-  initializers={
-    base=initializeprotrusion,
-    node=initializeprotrusion,
-  }
-}
-fonts.expansions=fonts.expansions    or {}
-fonts.expansions.setups=fonts.expansions.setups or {}
-local setups=fonts.expansions.setups
-local function initializeexpansion(tfmdata,value)
-  if value then
-    local setup=setups[value]
-    if setup then
-      local factor=setup.factor or 1
-      tfmdata.parameters.expansion={
-        stretch=10*(setup.stretch or 0),
-        shrink=10*(setup.shrink or 0),
-        step=10*(setup.step  or 0),
-        auto=true,
-      }
-      for i,chr in next,tfmdata.characters do
-        local v=setup[i]
-        if v and v~=0 then
-          chr.expansion_factor=v*factor
-        else 
-          chr.expansion_factor=factor
-        end
-      end
-    end
-  end
-end
-otffeatures.register {
-  name="expansion",
-  description="apply hz optimization",
-  initializers={
-    base=initializeexpansion,
-    node=initializeexpansion,
-  }
-}
-function fonts.loggers.onetimemessage() end
-local byte=string.byte
-fonts.expansions.setups['default']={
-  stretch=2,shrink=2,step=.5,factor=1,
-  [byte('A')]=0.5,[byte('B')]=0.7,[byte('C')]=0.7,[byte('D')]=0.5,[byte('E')]=0.7,
-  [byte('F')]=0.7,[byte('G')]=0.5,[byte('H')]=0.7,[byte('K')]=0.7,[byte('M')]=0.7,
-  [byte('N')]=0.7,[byte('O')]=0.5,[byte('P')]=0.7,[byte('Q')]=0.5,[byte('R')]=0.7,
-  [byte('S')]=0.7,[byte('U')]=0.7,[byte('W')]=0.7,[byte('Z')]=0.7,
-  [byte('a')]=0.7,[byte('b')]=0.7,[byte('c')]=0.7,[byte('d')]=0.7,[byte('e')]=0.7,
-  [byte('g')]=0.7,[byte('h')]=0.7,[byte('k')]=0.7,[byte('m')]=0.7,[byte('n')]=0.7,
-  [byte('o')]=0.7,[byte('p')]=0.7,[byte('q')]=0.7,[byte('s')]=0.7,[byte('u')]=0.7,
-  [byte('w')]=0.7,[byte('z')]=0.7,
-  [byte('2')]=0.7,[byte('3')]=0.7,[byte('6')]=0.7,[byte('8')]=0.7,[byte('9')]=0.7,
-}
-fonts.protrusions.setups['default']={
-  factor=1,left=1,right=1,
-  [0x002C]={ 0,1  },
-  [0x002E]={ 0,1  },
-  [0x003A]={ 0,1  },
-  [0x003B]={ 0,1  },
-  [0x002D]={ 0,1  },
-  [0x2013]={ 0,0.50 },
-  [0x2014]={ 0,0.33 },
-  [0x3001]={ 0,1  },
-  [0x3002]={ 0,1  },
-  [0x060C]={ 0,1  },
-  [0x061B]={ 0,1  },
-  [0x06D4]={ 0,1  },
-}
-fonts.handlers.otf.features.normalize=function(t)
-  if t.rand then
-    t.rand="random"
-  end
-  return t
-end
-function fonts.helpers.nametoslot(name)
-  local t=type(name)
-  if t=="string" then
-    local tfmdata=fonts.hashes.identifiers[currentfont()]
-    local shared=tfmdata and tfmdata.shared
-    local fntdata=shared and shared.rawdata
-    return fntdata and fntdata.resources.unicodes[name]
-  elseif t=="number" then
-    return n
-  end
-end
-fonts.encodings=fonts.encodings or {}
-local reencodings={}
-fonts.encodings.reencodings=reencodings
-local function specialreencode(tfmdata,value)
-  local encoding=value and reencodings[value]
-  if encoding then
-    local temp={}
-    local char=tfmdata.characters
-    for k,v in next,encoding do
-      temp[k]=char[v]
-    end
-    for k,v in next,temp do
-      char[k]=temp[k]
-    end
-    return string.format("reencoded:%s",value)
-  end
-end
-local function reencode(tfmdata,value)
-  tfmdata.postprocessors=tfmdata.postprocessors or {}
-  table.insert(tfmdata.postprocessors,
-    function(tfmdata)
-      return specialreencode(tfmdata,value)
-    end
-  )
-end
-otffeatures.register {
-  name="reencode",
-  description="reencode characters",
-  manipulators={
-    base=reencode,
-    node=reencode,
-  }
-}
-local function ignore(tfmdata,key,value)
-  if value then
-    tfmdata.mathparameters=nil
-  end
-end
-otffeatures.register {
-  name="ignoremathconstants",
-  description="ignore math constants table",
-  initializers={
-    base=ignore,
-    node=ignore,
-  }
-}
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “fonts-ext”] ---
-
-
-do  --- [luaotfload, fontloader-2017-02-11.lua scope for “font-gbn” 850f31ba73ff8de96371d0aed2b2b4cb] ---
-
-if not modules then modules={} end modules ['font-gbn']={
-  version=1.001,
-  comment="companion to luatex-*.tex",
-  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
-  copyright="PRAGMA ADE / ConTeXt Development Team",
-  license="see context related readme files"
-}
-if context then
-  texio.write_nl("fatal error: this module is not for context")
-  os.exit()
-end
-local fonts=fonts
-local nodes=nodes
-local nuts=nodes.nuts 
-local traverse_id=nuts.traverse_id
-local flush_node=nuts.flush_node
-local glyph_code=nodes.nodecodes.glyph
-local disc_code=nodes.nodecodes.disc
-local tonode=nuts.tonode
-local tonut=nuts.tonut
-local getfont=nuts.getfont
-local getchar=nuts.getchar
-local getid=nuts.getid
-local getboth=nuts.getboth
-local getprev=nuts.getprev
-local getnext=nuts.getnext
-local getdisc=nuts.getdisc
-local setchar=nuts.setchar
-local setlink=nuts.setlink
-local setprev=nuts.setprev
-local nodetail=nuts.tail
-local n_ligaturing=node.ligaturing
-local n_kerning=node.kerning
-local ligaturing=nuts.ligaturing
-local kerning=nuts.kerning
-local basemodepass=true
-local function l_warning() texio.write_nl("warning: node.ligaturing called directly") l_warning=nil end
-local function k_warning() texio.write_nl("warning: node.kerning called directly")  k_warning=nil end
-function node.ligaturing(...)
-  if basemodepass and l_warning then
-    l_warning()
-  end
-  return n_ligaturing(...)
-end
-function node.kerning(...)
-  if basemodepass and k_warning then
-    k_warning()
-  end
-  return n_kerning(...)
-end
-function nodes.handlers.setbasemodepass(v)
-  basemodepass=v
-end
-function nodes.handlers.nodepass(head)
-  local fontdata=fonts.hashes.identifiers
-  if fontdata then
-    local nuthead=tonut(head)
-    local usedfonts={}
-    local basefonts={}
-    local prevfont=nil
-    local basefont=nil
-    local variants=nil
-    local redundant=nil
-    for n in traverse_id(glyph_code,nuthead) do
-      local font=getfont(n)
-      if font~=prevfont then
-        if basefont then
-          basefont[2]=getprev(n)
-        end
-        prevfont=font
-        local used=usedfonts[font]
-        if not used then
-          local tfmdata=fontdata[font] 
-          if tfmdata then
-            local shared=tfmdata.shared 
-            if shared then
-              local processors=shared.processes
-              if processors and #processors>0 then
-                usedfonts[font]=processors
-              elseif basemodepass then
-                basefont={ n,nil }
-                basefonts[#basefonts+1]=basefont
-              end
-            end
-            local resources=tfmdata.resources
-            variants=resources and resources.variants
-            variants=variants and next(variants) and variants or false
-          end
-        else
-          local tfmdata=fontdata[prevfont]
-          if tfmdata then
-            local resources=tfmdata.resources
-            variants=resources and resources.variants
-            variants=variants and next(variants) and variants or false
-          end
-        end
-      end
-      if variants then
-        local char=getchar(n)
-        if char>=0xFE00 and (char<=0xFE0F or (char>=0xE0100 and char<=0xE01EF)) then
-          local hash=variants[char]
-          if hash then
-            local p=getprev(n)
-            if p and getid(p)==glyph_code then
-              local variant=hash[getchar(p)]
-              if variant then
-                setchar(p,variant)
-              end
-            end
-          end
-          if not redundant then
-            redundant={ n }
-          else
-            redundant[#redundant+1]=n
-          end
-        end
-      end
-    end
-    local nofbasefonts=#basefonts
-    if redundant then
-      for i=1,#redundant do
-        local r=redundant[i]
-        local p,n=getboth(r)
-        if r==nuthead then
-          nuthead=n
-          setprev(n)
-        else
-          setlink(p,n)
-        end
-        if nofbasefonts>0 then
-          for i=1,nofbasefonts do
-            local bi=basefonts[i]
-            if r==bi[1] then
-              bi[1]=n
-            end
-            if r==bi[2] then
-              bi[2]=n
-            end
-          end
-        end
-        flush_node(r)
-      end
-    end
-    for d in traverse_id(disc_code,nuthead) do
-      local _,_,r=getdisc(d)
-      if r then
-        for n in traverse_id(glyph_code,r) do
-          local font=getfont(n)
-          if font~=prevfont then
-            prevfont=font
-            local used=usedfonts[font]
-            if not used then
-              local tfmdata=fontdata[font] 
-              if tfmdata then
-                local shared=tfmdata.shared 
-                if shared then
-                  local processors=shared.processes
-                  if processors and #processors>0 then
-                    usedfonts[font]=processors
-                  end
-                end
-              end
-            end
-          end
-        end
-      end
-    end
-    if next(usedfonts) then
-      for font,processors in next,usedfonts do
-        for i=1,#processors do
-          head=processors[i](head,font,0) or head
-        end
-      end
-    end
-    if basemodepass and nofbasefonts>0 then
-      for i=1,nofbasefonts do
-        local range=basefonts[i]
-        local start=range[1]
-        local stop=range[2]
-        if start then
-          local front=nuthead==start
-          if not stop then
-            stop=nodetail(start)
-          end
-          if stop then
-            start,stop=ligaturing(start,stop)
-            start,stop=kerning(start,stop)
-          elseif start then 
-            start,stop=ligaturing(start,stop)
-            start,stop=kerning(start,stop)
-          end
-          if front and nuthead~=start then
-            head=tonode(start)
-          end
-        end
-      end
-    end
-    return head,true
-  else
-    return head,false
-  end
-end
-function nodes.handlers.basepass(head)
-  if not basemodepass then
-    head=n_ligaturing(head)
-    head=n_kerning(head)
-  end
-  return head,true
-end
-local nodepass=nodes.handlers.nodepass
-local basepass=nodes.handlers.basepass
-local injectpass=nodes.injections.handler
-local protectpass=nodes.handlers.protectglyphs
-function nodes.simple_font_handler(head)
-  if head then
-    head=nodepass(head)
-    head=injectpass(head)
-    if not basemodepass then
-      head=basepass(head)
-    end
-    protectpass(head)
-    return head,true
-  else
-    return head,false
-  end
-end
-
-end --- [luaotfload, fontloader-2017-02-11.lua scope for “font-gbn”] ---
-
-
---- vim:ft=lua:sw=2:ts=8:et:tw=79

Added: trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2018-09-24.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2018-09-24.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2018-09-24.lua	2018-09-26 20:50:34 UTC (rev 48771)
@@ -0,0 +1,29266 @@
+--[[info-----------------------------------------------------------------------
+  Luaotfload fontloader package
+  build 2018-09-24 22:51:46 by fischer at troubleshooting-tex.de
+-------------------------------------------------------------------------------
+
+  © 2018 PRAGMA ADE / ConTeXt Development Team
+
+  The code in this file is provided under the GPL v2.0 license. See the
+  file COPYING in the Luaotfload repository for details.
+
+  Report bugs to github.com/lualatex/luaotfload
+
+  This file has been assembled from components taken from Context. See
+  the Luaotfload documentation for details:
+
+      $ texdoc luaotfload
+      $ man 1 luaotfload-tool
+      $ man 5 luaotfload.conf
+
+  Included files:
+
+    · fontloader-data-con.lua
+    · fontloader-basics-nod.lua
+    · fontloader-font-ini.lua
+    · fontloader-fonts-mis.lua
+    · fontloader-font-con.lua
+    · fontloader-fonts-enc.lua
+    · fontloader-font-cid.lua
+    · fontloader-font-map.lua
+    · fontloader-font-vfc.lua
+    · fontloader-font-otr.lua
+    · fontloader-font-oti.lua
+    · fontloader-font-ott.lua
+    · fontloader-font-cff.lua
+    · fontloader-font-ttf.lua
+    · fontloader-font-dsp.lua
+    · fontloader-font-oup.lua
+    · fontloader-font-otl.lua
+    · fontloader-font-oto.lua
+    · fontloader-font-otj.lua
+    · fontloader-font-ota.lua
+    · fontloader-font-ots.lua
+    · fontloader-font-osd.lua
+    · fontloader-font-ocl.lua
+    · fontloader-font-otc.lua
+    · fontloader-font-onr.lua
+    · fontloader-font-one.lua
+    · fontloader-font-afk.lua
+    · fontloader-font-tfm.lua
+    · fontloader-font-lua.lua
+    · fontloader-font-def.lua
+    · fontloader-fonts-def.lua
+    · fontloader-fonts-ext.lua
+    · fontloader-font-imp-tex.lua
+    · fontloader-font-imp-ligatures.lua
+    · fontloader-font-imp-italics.lua
+    · fontloader-font-imp-effects.lua
+    · fontloader-fonts-lig.lua
+    · fontloader-fonts-gbn.lua
+
+--info]]-----------------------------------------------------------------------
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “data-con” d8982c834ed9acc6193eee23067b9d5d] ---
+
+if not modules then modules={} end modules ['data-con']={
+  version=1.100,
+  comment="companion to luat-lib.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+local format,lower,gsub=string.format,string.lower,string.gsub
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
+local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
+containers=containers or {}
+local containers=containers
+containers.usecache=true
+local report_containers=logs.reporter("resolvers","containers")
+local allocated={}
+local mt={
+  __index=function(t,k)
+    if k=="writable" then
+      local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
+      t.writable=writable
+      return writable
+    elseif k=="readables" then
+      local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
+      t.readables=readables
+      return readables
+    end
+  end,
+  __storage__=true
+}
+function containers.define(category,subcategory,version,enabled)
+  if category and subcategory then
+    local c=allocated[category]
+    if not c then
+      c={}
+      allocated[category]=c
+    end
+    local s=c[subcategory]
+    if not s then
+      s={
+        category=category,
+        subcategory=subcategory,
+        storage={},
+        enabled=enabled,
+        version=version or math.pi,
+        trace=false,
+      }
+      setmetatable(s,mt)
+      c[subcategory]=s
+    end
+    return s
+  end
+end
+function containers.is_usable(container,name)
+  return container.enabled and caches and caches.is_writable(container.writable,name)
+end
+function containers.is_valid(container,name)
+  if name and name~="" then
+    local storage=container.storage[name]
+    return storage and storage.cache_version==container.version
+  else
+    return false
+  end
+end
+function containers.read(container,name)
+  local storage=container.storage
+  local stored=storage[name]
+  if not stored and container.enabled and caches and containers.usecache then
+    stored=caches.loaddata(container.readables,name,container.writable)
+    if stored and stored.cache_version==container.version then
+      if trace_cache or trace_containers then
+        report_containers("action %a, category %a, name %a","load",container.subcategory,name)
+      end
+    else
+      stored=nil
+    end
+    storage[name]=stored
+  elseif stored then
+    if trace_cache or trace_containers then
+      report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
+    end
+  end
+  return stored
+end
+function containers.write(container,name,data)
+  if data then
+    data.cache_version=container.version
+    if container.enabled and caches then
+      local unique,shared=data.unique,data.shared
+      data.unique,data.shared=nil,nil
+      caches.savedata(container.writable,name,data)
+      if trace_cache or trace_containers then
+        report_containers("action %a, category %a, name %a","save",container.subcategory,name)
+      end
+      data.unique,data.shared=unique,shared
+    end
+    if trace_cache or trace_containers then
+      report_containers("action %a, category %a, name %a","store",container.subcategory,name)
+    end
+    container.storage[name]=data
+  end
+  return data
+end
+function containers.content(container,name)
+  return container.storage[name]
+end
+function containers.cleanname(name)
+  return (gsub(lower(name),"[^%w\128-\255]+","-")) 
+end
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “data-con”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “basics-nod” 78f56219685f3145b9393c2b688aad94] ---
+
+if not modules then modules={} end modules ['luatex-fonts-nod']={
+  version=1.001,
+  comment="companion to luatex-fonts.lua",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+if context then
+  os.exit()
+end
+if tex.attribute[0]~=0 then
+  texio.write_nl("log","!")
+  texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be")
+  texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special")
+  texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.")
+  texio.write_nl("log","!")
+  tex.attribute[0]=0 
+end
+attributes=attributes or {}
+attributes.unsetvalue=-0x7FFFFFFF
+local numbers,last={},127
+attributes.private=attributes.private or function(name)
+  local number=numbers[name]
+  if not number then
+    if last<255 then
+      last=last+1
+    end
+    number=last
+    numbers[name]=number
+  end
+  return number
+end
+nodes={}
+nodes.handlers={}
+local nodecodes={}
+local glyphcodes=node.subtypes("glyph")
+local disccodes=node.subtypes("disc")
+for k,v in next,node.types() do
+  v=string.gsub(v,"_","")
+  nodecodes[k]=v
+  nodecodes[v]=k
+end
+for k,v in next,glyphcodes do
+  glyphcodes[v]=k
+end
+for k,v in next,glyphcodes do
+  disccodes[v]=k
+end
+nodes.nodecodes=nodecodes
+nodes.glyphcodes=glyphcodes
+nodes.disccodes=disccodes
+local flush_node=node.flush_node
+local remove_node=node.remove
+local traverse_id=node.traverse_id
+nodes.handlers.protectglyphs=node.protect_glyphs  
+nodes.handlers.unprotectglyphs=node.unprotect_glyphs 
+local math_code=nodecodes.math
+local end_of_math=node.end_of_math
+function node.end_of_math(n)
+  if n.id==math_code and n.subtype==1 then
+    return n
+  else
+    return end_of_math(n)
+  end
+end
+function nodes.remove(head,current,free_too)
+  local t=current
+  head,current=remove_node(head,current)
+  if t then
+    if free_too then
+      flush_node(t)
+      t=nil
+    else
+      t.next,t.prev=nil,nil
+    end
+  end
+  return head,current,t
+end
+function nodes.delete(head,current)
+  return nodes.remove(head,current,true)
+end
+local getfield=node.getfield
+local setfield=node.setfield
+nodes.getfield=getfield
+nodes.setfield=setfield
+nodes.getattr=getfield
+nodes.setattr=setfield
+nodes.tostring=node.tostring or tostring
+nodes.copy=node.copy
+nodes.copy_node=node.copy
+nodes.copy_list=node.copy_list
+nodes.delete=node.delete
+nodes.dimensions=node.dimensions
+nodes.end_of_math=node.end_of_math
+nodes.flush_list=node.flush_list
+nodes.flush_node=node.flush_node
+nodes.flush=node.flush_node
+nodes.free=node.free
+nodes.insert_after=node.insert_after
+nodes.insert_before=node.insert_before
+nodes.hpack=node.hpack
+nodes.new=node.new
+nodes.tail=node.tail
+nodes.traverse=node.traverse
+nodes.traverse_id=node.traverse_id
+nodes.slide=node.slide
+nodes.vpack=node.vpack
+nodes.first_glyph=node.first_glyph
+nodes.has_glyph=node.has_glyph or node.first_glyph
+nodes.current_attr=node.current_attr
+nodes.has_field=node.has_field
+nodes.last_node=node.last_node
+nodes.usedlist=node.usedlist
+nodes.protrusion_skippable=node.protrusion_skippable
+nodes.write=node.write
+nodes.has_attribute=node.has_attribute
+nodes.set_attribute=node.set_attribute
+nodes.unset_attribute=node.unset_attribute
+nodes.protect_glyphs=node.protect_glyphs
+nodes.unprotect_glyphs=node.unprotect_glyphs
+nodes.mlist_to_hlist=node.mlist_to_hlist
+local direct=node.direct
+local nuts={}
+nodes.nuts=nuts
+local tonode=direct.tonode
+local tonut=direct.todirect
+nodes.tonode=tonode
+nodes.tonut=tonut
+nuts.tonode=tonode
+nuts.tonut=tonut
+local getfield=direct.getfield
+local setfield=direct.setfield
+nuts.getfield=getfield
+nuts.setfield=setfield
+nuts.getnext=direct.getnext
+nuts.setnext=direct.setnext
+nuts.getprev=direct.getprev
+nuts.setprev=direct.setprev
+nuts.getboth=direct.getboth
+nuts.setboth=direct.setboth
+nuts.getid=direct.getid
+nuts.getattr=direct.get_attribute or direct.has_attribute or getfield
+nuts.setattr=setfield
+nuts.getfont=direct.getfont
+nuts.setfont=direct.setfont
+nuts.getsubtype=direct.getsubtype
+nuts.setsubtype=direct.setsubtype
+nuts.getchar=direct.getchar
+nuts.setchar=direct.setchar
+nuts.getdisc=direct.getdisc
+nuts.setdisc=direct.setdisc
+nuts.setlink=direct.setlink
+nuts.setsplit=direct.setsplit
+nuts.getlist=direct.getlist
+nuts.setlist=direct.setlist
+nuts.getoffsets=direct.getoffsets or
+  function(n)
+    return getfield(n,"xoffset"),getfield(n,"yoffset")
+  end
+nuts.setoffsets=direct.setoffsets or
+  function(n,x,y)
+    if x then setfield(n,"xoffset",x) end
+    if y then setfield(n,"xoffset",y) end
+  end
+nuts.getleader=direct.getleader   or function(n)  return getfield(n,"leader")    end
+nuts.setleader=direct.setleader   or function(n,l)    setfield(n,"leader",l)   end
+nuts.getcomponents=direct.getcomponents or function(n)  return getfield(n,"components")  end
+nuts.setcomponents=direct.setcomponents or function(n,c)    setfield(n,"components",c) end
+nuts.getkern=direct.getkern    or function(n)  return getfield(n,"kern")     end
+nuts.setkern=direct.setkern    or function(n,k)    setfield(n,"kern",k)    end
+nuts.getdir=direct.getdir    or function(n)  return getfield(n,"dir")     end
+nuts.setdir=direct.setdir    or function(n,d)    setfield(n,"dir",d)    end
+nuts.getwidth=direct.getwidth   or function(n)  return getfield(n,"width")    end
+nuts.setwidth=direct.setwidth   or function(n,w) return setfield(n,"width",w)   end
+nuts.getheight=direct.getheight   or function(n)  return getfield(n,"height")    end
+nuts.setheight=direct.setheight   or function(n,h) return setfield(n,"height",h)   end
+nuts.getdepth=direct.getdepth   or function(n)  return getfield(n,"depth")    end
+nuts.setdepth=direct.setdepth   or function(n,d) return setfield(n,"depth",d)   end
+if not direct.is_glyph then
+  local getchar=direct.getchar
+  local getid=direct.getid
+  local getfont=direct.getfont
+  local glyph_code=nodes.nodecodes.glyph
+  function direct.is_glyph(n,f)
+    local id=getid(n)
+    if id==glyph_code then
+      if f and getfont(n)==f then
+        return getchar(n)
+      else
+        return false
+      end
+    else
+      return nil,id
+    end
+  end
+  function direct.is_char(n,f)
+    local id=getid(n)
+    if id==glyph_code then
+      if getsubtype(n)>=256 then
+        return false
+      elseif f and getfont(n)==f then
+        return getchar(n)
+      else
+        return false
+      end
+    else
+      return nil,id
+    end
+  end
+end
+nuts.ischar=direct.is_char
+nuts.is_char=direct.is_char
+nuts.isglyph=direct.is_glyph
+nuts.is_glyph=direct.is_glyph
+nuts.insert_before=direct.insert_before
+nuts.insert_after=direct.insert_after
+nuts.delete=direct.delete
+nuts.copy=direct.copy
+nuts.copy_node=direct.copy
+nuts.copy_list=direct.copy_list
+nuts.tail=direct.tail
+nuts.flush_list=direct.flush_list
+nuts.flush_node=direct.flush_node
+nuts.flush=direct.flush
+nuts.free=direct.free
+nuts.remove=direct.remove
+nuts.is_node=direct.is_node
+nuts.end_of_math=direct.end_of_math
+nuts.traverse=direct.traverse
+nuts.traverse_id=direct.traverse_id
+nuts.traverse_char=direct.traverse_char
+nuts.traverse_glyph=direct.traverse_glyph
+nuts.ligaturing=direct.ligaturing
+nuts.kerning=direct.kerning
+nuts.new=direct.new
+nuts.getprop=nuts.getattr
+nuts.setprop=nuts.setattr
+local propertydata=direct.get_properties_table()
+nodes.properties={ data=propertydata }
+direct.set_properties_mode(true,true)   
+function direct.set_properties_mode() end 
+nuts.getprop=function(n,k)
+  local p=propertydata[n]
+  if p then
+    return p[k]
+  end
+end
+nuts.setprop=function(n,k,v)
+  if v then
+    local p=propertydata[n]
+    if p then
+      p[k]=v
+    else
+      propertydata[n]={ [k]=v }
+    end
+  end
+end
+nodes.setprop=nodes.setproperty
+nodes.getprop=nodes.getproperty
+local setprev=nuts.setprev
+local setnext=nuts.setnext
+local getnext=nuts.getnext
+local setlink=nuts.setlink
+local getfield=nuts.getfield
+local setfield=nuts.setfield
+local getcomponents=nuts.getcomponents
+local setcomponents=nuts.setcomponents
+local find_tail=nuts.tail
+local flush_list=nuts.flush_list
+local flush_node=nuts.flush_node
+local traverse_id=nuts.traverse_id
+local copy_node=nuts.copy_node
+local glyph_code=nodes.nodecodes.glyph
+function nuts.set_components(target,start,stop)
+  local head=getcomponents(target)
+  if head then
+    flush_list(head)
+    head=nil
+  end
+  if start then
+    setprev(start)
+  else
+    return nil
+  end
+  if stop then
+    setnext(stop)
+  end
+  local tail=nil
+  while start do
+    local c=getcomponents(start)
+    local n=getnext(start)
+    if c then
+      if head then
+        setlink(tail,c)
+      else
+        head=c
+      end
+      tail=find_tail(c)
+      setcomponents(start)
+      flush_node(start)
+    else
+      if head then
+        setlink(tail,start)
+      else
+        head=start
+      end
+      tail=start
+    end
+    start=n
+  end
+  setcomponents(target,head)
+  return head
+end
+nuts.get_components=nuts.getcomponents
+function nuts.take_components(target)
+  local c=getcomponents(target)
+  setcomponents(target)
+  return c
+end
+function nuts.count_components(n,marks)
+  local components=getcomponents(n)
+  if components then
+    if marks then
+      local i=0
+      for g in traverse_id(glyph_code,components) do
+        if not marks[getchar(g)] then
+          i=i+1
+        end
+      end
+      return i
+    else
+      return count(glyph_code,components)
+    end
+  else
+    return 0
+  end
+end
+function nuts.copy_no_components(g,copyinjection)
+  local components=getcomponents(g)
+  if components then
+    setcomponents(g)
+    local n=copy_node(g)
+    if copyinjection then
+      copyinjection(n,g)
+    end
+    setcomponents(g,components)
+    return n
+  else
+    local n=copy_node(g)
+    if copyinjection then
+      copyinjection(n,g)
+    end
+    return n
+  end
+end
+function nuts.copy_only_glyphs(current)
+  local head=nil
+  local previous=nil
+  for n in traverse_id(glyph_code,current) do
+    n=copy_node(n)
+    if head then
+      setlink(previous,n)
+    else
+      head=n
+    end
+    previous=n
+  end
+  return head
+end
+nuts.uses_font=direct.uses_font
+if not nuts.uses_font then
+  local getdisc=nuts.getdisc
+  local getfont=nuts.getfont
+  function nuts.uses_font(n,font)
+    local pre,post,replace=getdisc(n)
+    if pre then
+      for n in traverse_id(glyph_code,pre) do
+        if getfont(n)==font then
+          return true
+        end
+      end
+    end
+    if post then
+      for n in traverse_id(glyph_code,post) do
+        if getfont(n)==font then
+          return true
+        end
+      end
+    end
+    if replace then
+      for n in traverse_id(glyph_code,replace) do
+        if getfont(n)==font then
+          return true
+        end
+      end
+    end
+    return false
+  end
+end
+do
+  local dummy=tonut(node.new("glyph"))
+  nuts.traversers={
+    glyph=nuts.traverse_id(nodecodes.glyph,dummy),
+    glue=nuts.traverse_id(nodecodes.glue,dummy),
+    disc=nuts.traverse_id(nodecodes.disc,dummy),
+    boundary=nuts.traverse_id(nodecodes.boundary,dummy),
+    char=nuts.traverse_char(dummy),
+    node=nuts.traverse(dummy),
+  }
+end
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “basics-nod”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “font-ini” 6f615d3bc72fb29f409ed2b8f6364c35] ---
+
+if not modules then modules={} end modules ['font-ini']={
+  version=1.001,
+  comment="companion to font-ini.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+local allocate=utilities.storage.allocate
+fonts=fonts or {}
+local fonts=fonts
+fonts.hashes=fonts.hashes   or { identifiers=allocate() }
+fonts.tables=fonts.tables   or {}
+fonts.helpers=fonts.helpers  or {}
+fonts.tracers=fonts.tracers  or {} 
+fonts.specifiers=fonts.specifiers or {} 
+fonts.analyzers={} 
+fonts.readers={}
+fonts.definers={ methods={} }
+fonts.loggers={ register=function() end }
+if context then
+  fontloader=nil
+end
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “font-ini”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “fonts-mis” fd0a52acf5180695d2870da654db7272] ---
+
+if not modules then modules={} end modules ['luatex-font-mis']={
+  version=1.001,
+  comment="companion to luatex-*.tex",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+if context then
+  os.exit()
+end
+local currentfont=font.current
+local hashes=fonts.hashes
+local identifiers=hashes.identifiers or {}
+local marks=hashes.marks    or {}
+hashes.identifiers=identifiers
+hashes.marks=marks
+table.setmetatableindex(marks,function(t,k)
+  if k==true then
+    return marks[currentfont()]
+  else
+    local resources=identifiers[k].resources or {}
+    local marks=resources.marks or {}
+    t[k]=marks
+    return marks
+  end
+end)
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “fonts-mis”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “font-con” 3218bd21a24c2abb13b284085da8ced4] ---
+
+if not modules then modules={} end modules ['font-con']={
+  version=1.001,
+  comment="companion to font-ini.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+local next,tostring,tonumber,rawget=next,tostring,tonumber,rawget
+local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find
+local sort,insert,concat=table.sort,table.insert,table.concat
+local sortedkeys,sortedhash,serialize,fastcopy=table.sortedkeys,table.sortedhash,table.serialize,table.fastcopy
+local derivetable=table.derive
+local ioflush=io.flush
+local round=math.round
+local setmetatable,getmetatable,rawget,rawset=setmetatable,getmetatable,rawget,rawset
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end)
+local report_defining=logs.reporter("fonts","defining")
+local fonts=fonts
+local constructors=fonts.constructors or {}
+fonts.constructors=constructors
+local handlers=fonts.handlers or {} 
+fonts.handlers=handlers
+local allocate=utilities.storage.allocate
+local setmetatableindex=table.setmetatableindex
+constructors.dontembed=allocate()
+constructors.autocleanup=true
+constructors.namemode="fullpath" 
+constructors.version=1.01
+constructors.cache=containers.define("fonts","constructors",constructors.version,false)
+constructors.privateoffset=0xF0000 
+constructors.cacheintex=true
+local designsizes=allocate()
+constructors.designsizes=designsizes
+local loadedfonts=allocate()
+constructors.loadedfonts=loadedfonts
+local factors={
+  pt=65536.0,
+  bp=65781.8,
+}
+function constructors.setfactor(f)
+  constructors.factor=factors[f or 'pt'] or factors.pt
+end
+constructors.setfactor()
+function constructors.scaled(scaledpoints,designsize) 
+  if scaledpoints<0 then
+    local factor=constructors.factor
+    if designsize then
+      if designsize>factor then 
+        return (- scaledpoints/1000)*designsize 
+      else
+        return (- scaledpoints/1000)*designsize*factor
+      end
+    else
+      return (- scaledpoints/1000)*10*factor
+    end
+  else
+    return scaledpoints
+  end
+end
+function constructors.getprivate(tfmdata)
+  local properties=tfmdata.properties
+  local private=properties.private
+  properties.private=private+1
+  return private
+end
+function constructors.setmathparameter(tfmdata,name,value)
+  local m=tfmdata.mathparameters
+  local c=tfmdata.MathConstants
+  if m then
+    m[name]=value
+  end
+  if c and c~=m then
+    c[name]=value
+  end
+end
+function constructors.getmathparameter(tfmdata,name)
+  local p=tfmdata.mathparameters or tfmdata.MathConstants
+  if p then
+    return p[name]
+  end
+end
+function constructors.cleanuptable(tfmdata)
+  if constructors.autocleanup and tfmdata.properties.virtualized then
+    for k,v in next,tfmdata.characters do
+      if v.commands then v.commands=nil end
+    end
+  end
+end
+function constructors.calculatescale(tfmdata,scaledpoints)
+  local parameters=tfmdata.parameters
+  if scaledpoints<0 then
+    scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize) 
+  end
+  return scaledpoints,scaledpoints/(parameters.units or 1000) 
+end
+local unscaled={
+  ScriptPercentScaleDown=true,
+  ScriptScriptPercentScaleDown=true,
+  RadicalDegreeBottomRaisePercent=true,
+  NoLimitSupFactor=true,
+  NoLimitSubFactor=true,
+}
+function constructors.assignmathparameters(target,original)
+  local mathparameters=original.mathparameters
+  if mathparameters and next(mathparameters) then
+    local targetparameters=target.parameters
+    local targetproperties=target.properties
+    local targetmathparameters={}
+    local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor
+    for name,value in next,mathparameters do
+      if unscaled[name] then
+        targetmathparameters[name]=value
+      else
+        targetmathparameters[name]=value*factor
+      end
+    end
+    if not targetmathparameters.FractionDelimiterSize then
+      targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size
+    end
+    if not mathparameters.FractionDelimiterDisplayStyleSize then
+      targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size
+    end
+    target.mathparameters=targetmathparameters
+  end
+end
+function constructors.beforecopyingcharacters(target,original)
+end
+function constructors.aftercopyingcharacters(target,original)
+end
+constructors.sharefonts=false
+constructors.nofsharedfonts=0
+local sharednames={}
+function constructors.trytosharefont(target,tfmdata)
+  if constructors.sharefonts then 
+    local characters=target.characters
+    local n=1
+    local t={ target.psname }
+    local u=sortedkeys(characters)
+    for i=1,#u do
+      local k=u[i]
+      n=n+1;t[n]=k
+      n=n+1;t[n]=characters[k].index or k
+    end
+    local h=md5.HEX(concat(t," "))
+    local s=sharednames[h]
+    if s then
+      if trace_defining then
+        report_defining("font %a uses backend resources of font %a",target.fullname,s)
+      end
+      target.fullname=s
+      constructors.nofsharedfonts=constructors.nofsharedfonts+1
+      target.properties.sharedwith=s
+    else
+      sharednames[h]=target.fullname
+    end
+  end
+end
+local synonyms={
+  exheight="x_height",
+  xheight="x_height",
+  ex="x_height",
+  emwidth="quad",
+  em="quad",
+  spacestretch="space_stretch",
+  stretch="space_stretch",
+  spaceshrink="space_shrink",
+  shrink="space_shrink",
+  extraspace="extra_space",
+  xspace="extra_space",
+  slantperpoint="slant",
+}
+function constructors.enhanceparameters(parameters)
+  local mt=getmetatable(parameters)
+  local getter=function(t,k)
+    if not k then
+      return nil
+    end
+    local s=synonyms[k]
+    if s then
+      return rawget(t,s) or (mt and mt[s]) or nil
+    end
+    if k=="spacing" then
+      return {
+        width=t.space,
+        stretch=t.space_stretch,
+        shrink=t.space_shrink,
+        extra=t.extra_space,
+      }
+    end
+    return mt and mt[k] or nil
+  end
+  local setter=function(t,k,v)
+    if not k then
+      return 0
+    end
+    local s=synonyms[k]
+    if s then
+      rawset(t,s,v)
+    elseif k=="spacing" then
+      if type(v)=="table" then
+        rawset(t,"space",v.width or 0)
+        rawset(t,"space_stretch",v.stretch or 0)
+        rawset(t,"space_shrink",v.shrink or 0)
+        rawset(t,"extra_space",v.extra or 0)
+      end
+    else
+      rawset(t,k,v)
+    end
+  end
+  setmetatable(parameters,{
+    __index=getter,
+    __newindex=setter,
+  })
+end
+local function mathkerns(v,vdelta)
+  local k={}
+  for i=1,#v do
+    local entry=v[i]
+    local height=entry.height
+    local kern=entry.kern
+    k[i]={
+      height=height and vdelta*height or 0,
+      kern=kern  and vdelta*kern  or 0,
+    }
+  end
+  return k
+end
+local psfake=0
+local function fixedpsname(psname,fallback)
+  local usedname=psname
+  if psname and psname~="" then
+    if find(psname," ",1,true) then
+      usedname=gsub(psname,"[%s]+","-")
+    else
+    end
+  elseif not fallback or fallback=="" then
+    psfake=psfake+1
+    psname="fakename-"..psfake
+  else
+    psname=fallback
+    usedname=gsub(psname,"[^a-zA-Z0-9]+","-")
+  end
+  return usedname,psname~=usedname
+end
+function constructors.scale(tfmdata,specification)
+  local target={}
+  if tonumber(specification) then
+    specification={ size=specification }
+  end
+  target.specification=specification
+  local scaledpoints=specification.size
+  local relativeid=specification.relativeid
+  local properties=tfmdata.properties   or {}
+  local goodies=tfmdata.goodies    or {}
+  local resources=tfmdata.resources   or {}
+  local descriptions=tfmdata.descriptions  or {} 
+  local characters=tfmdata.characters   or {} 
+  local changed=tfmdata.changed    or {} 
+  local shared=tfmdata.shared     or {}
+  local parameters=tfmdata.parameters   or {}
+  local mathparameters=tfmdata.mathparameters or {}
+  local targetcharacters={}
+  local targetdescriptions=derivetable(descriptions)
+  local targetparameters=derivetable(parameters)
+  local targetproperties=derivetable(properties)
+  local targetgoodies=goodies            
+  target.characters=targetcharacters
+  target.descriptions=targetdescriptions
+  target.parameters=targetparameters
+  target.properties=targetproperties
+  target.goodies=targetgoodies
+  target.shared=shared
+  target.resources=resources
+  target.unscaled=tfmdata
+  local mathsize=tonumber(specification.mathsize) or 0
+  local textsize=tonumber(specification.textsize) or scaledpoints
+  local forcedsize=tonumber(parameters.mathsize  ) or 0 
+  local extrafactor=tonumber(specification.factor ) or 1
+  if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then
+    scaledpoints=parameters.scriptpercentage*textsize/100
+  elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then
+    scaledpoints=parameters.scriptscriptpercentage*textsize/100
+  elseif forcedsize>1000 then 
+    scaledpoints=forcedsize
+  else
+  end
+  targetparameters.mathsize=mathsize  
+  targetparameters.textsize=textsize  
+  targetparameters.forcedsize=forcedsize 
+  targetparameters.extrafactor=extrafactor
+  local tounicode=fonts.mappings.tounicode
+  local defaultwidth=resources.defaultwidth or 0
+  local defaultheight=resources.defaultheight or 0
+  local defaultdepth=resources.defaultdepth or 0
+  local units=parameters.units or 1000
+  targetproperties.language=properties.language or "dflt" 
+  targetproperties.script=properties.script  or "dflt" 
+  targetproperties.mode=properties.mode   or "base"
+  local askedscaledpoints=scaledpoints
+  local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification)
+  local hdelta=delta
+  local vdelta=delta
+  target.designsize=parameters.designsize 
+  target.units=units
+  target.units_per_em=units
+  local direction=properties.direction or tfmdata.direction or 0 
+  target.direction=direction
+  properties.direction=direction
+  target.size=scaledpoints
+  target.encodingbytes=properties.encodingbytes or 1
+  target.embedding=properties.embedding or "subset"
+  target.tounicode=1
+  target.cidinfo=properties.cidinfo
+  target.format=properties.format
+  target.cache=constructors.cacheintex and "yes" or "renew"
+  local fontname=properties.fontname or tfmdata.fontname
+  local fullname=properties.fullname or tfmdata.fullname
+  local filename=properties.filename or tfmdata.filename
+  local psname=properties.psname  or tfmdata.psname
+  local name=properties.name   or tfmdata.name
+  local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename))
+  target.fontname=fontname
+  target.fullname=fullname
+  target.filename=filename
+  target.psname=psname
+  target.name=name
+  properties.fontname=fontname
+  properties.fullname=fullname
+  properties.filename=filename
+  properties.psname=psname
+  properties.name=name
+  local expansion=parameters.expansion
+  if expansion then
+    target.stretch=expansion.stretch
+    target.shrink=expansion.shrink
+    target.step=expansion.step
+  end
+  local slantfactor=parameters.slantfactor or 0
+  if slantfactor~=0 then
+    target.slant=slantfactor*1000
+  else
+    target.slant=0
+  end
+  local extendfactor=parameters.extendfactor or 0
+  if extendfactor~=0 and extendfactor~=1 then
+    hdelta=hdelta*extendfactor
+    target.extend=extendfactor*1000
+  else
+    target.extend=1000 
+  end
+  local squeezefactor=parameters.squeezefactor or 0
+  if squeezefactor~=0 and squeezefactor~=1 then
+    vdelta=vdelta*squeezefactor
+    target.squeeze=squeezefactor*1000
+  else
+    target.squeeze=1000 
+  end
+  local mode=parameters.mode or 0
+  if mode~=0 then
+    target.mode=mode
+  end
+  local width=parameters.width or 0
+  if width~=0 then
+    target.width=width*delta*1000/655360
+  end
+  targetparameters.factor=delta
+  targetparameters.hfactor=hdelta
+  targetparameters.vfactor=vdelta
+  targetparameters.size=scaledpoints
+  targetparameters.units=units
+  targetparameters.scaledpoints=askedscaledpoints
+  targetparameters.mode=mode
+  targetparameters.width=width
+  local isvirtual=properties.virtualized or tfmdata.type=="virtual"
+  local hasquality=parameters.expansion or parameters.protrusion
+  local hasitalics=properties.hasitalics
+  local autoitalicamount=properties.autoitalicamount
+  local stackmath=not properties.nostackmath
+  local nonames=properties.noglyphnames
+  local haskerns=properties.haskerns   or properties.mode=="base" 
+  local hasligatures=properties.hasligatures or properties.mode=="base" 
+  local realdimensions=properties.realdimensions
+  local writingmode=properties.writingmode or "horizontal"
+  local identity=properties.identity or "horizontal"
+  local vfonts=target.fonts
+  if vfonts and #vfonts>0 then
+    target.fonts=fastcopy(vfonts) 
+  elseif isvirtual then
+    target.fonts={ { id=0 } } 
+  end
+  if changed and not next(changed) then
+    changed=false
+  end
+  target.type=isvirtual and "virtual" or "real"
+  target.writingmode=writingmode=="vertical" and "vertical" or "horizontal"
+  target.identity=identity=="vertical" and "vertical" or "horizontal"
+  target.postprocessors=tfmdata.postprocessors
+  local targetslant=(parameters.slant     or parameters[1] or 0)*factors.pt 
+  local targetspace=(parameters.space     or parameters[2] or 0)*hdelta
+  local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta
+  local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta
+  local targetx_height=(parameters.x_height   or parameters[5] or 0)*vdelta
+  local targetquad=(parameters.quad     or parameters[6] or 0)*hdelta
+  local targetextra_space=(parameters.extra_space  or parameters[7] or 0)*hdelta
+  targetparameters.slant=targetslant 
+  targetparameters.space=targetspace
+  targetparameters.space_stretch=targetspace_stretch
+  targetparameters.space_shrink=targetspace_shrink
+  targetparameters.x_height=targetx_height
+  targetparameters.quad=targetquad
+  targetparameters.extra_space=targetextra_space
+  local ascender=parameters.ascender
+  if ascender then
+    targetparameters.ascender=delta*ascender
+  end
+  local descender=parameters.descender
+  if descender then
+    targetparameters.descender=delta*descender
+  end
+  constructors.enhanceparameters(targetparameters)
+  local protrusionfactor=(targetquad~=0 and 1000/targetquad) or 0
+  local scaledwidth=defaultwidth*hdelta
+  local scaledheight=defaultheight*vdelta
+  local scaleddepth=defaultdepth*vdelta
+  local hasmath=(properties.hasmath or next(mathparameters)) and true
+  if hasmath then
+    constructors.assignmathparameters(target,tfmdata) 
+    properties.hasmath=true
+    target.nomath=false
+    target.MathConstants=target.mathparameters
+  else
+    properties.hasmath=false
+    target.nomath=true
+    target.mathparameters=nil 
+  end
+  if hasmath then
+    local mathitalics=properties.mathitalics
+    if mathitalics==false then
+      if trace_defining then
+        report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename)
+      end
+      hasitalics=false
+      autoitalicamount=false
+    end
+  else
+    local textitalics=properties.textitalics
+    if textitalics==false then
+      if trace_defining then
+        report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename)
+      end
+      hasitalics=false
+      autoitalicamount=false
+    end
+  end
+  if trace_defining then
+    report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a",
+      name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta,
+      hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled")
+  end
+  constructors.beforecopyingcharacters(target,tfmdata)
+  local sharedkerns={}
+  for unicode,character in next,characters do
+    local chr,description,index
+    if changed then
+      local c=changed[unicode]
+      if c and c~=unicode then
+        if c then
+          description=descriptions[c] or descriptions[unicode] or character
+          character=characters[c] or character
+          index=description.index or c
+        else
+          description=descriptions[unicode] or character
+          index=description.index or unicode
+        end
+      else
+        description=descriptions[unicode] or character
+        index=description.index or unicode
+      end
+    else
+      description=descriptions[unicode] or character
+      index=description.index or unicode
+    end
+    local width=description.width
+    local height=description.height
+    local depth=description.depth
+    if realdimensions then
+      if not height or height==0 then
+        local bb=description.boundingbox
+        local ht=bb[4]
+        if ht~=0 then
+          height=ht
+        end
+        if not depth or depth==0 then
+          local dp=-bb[2]
+          if dp~=0 then
+            depth=dp
+          end
+        end
+      elseif not depth or depth==0 then
+        local dp=-description.boundingbox[2]
+        if dp~=0 then
+          depth=dp
+        end
+      end
+    end
+    if width then width=hdelta*width else width=scaledwidth end
+    if height then height=vdelta*height else height=scaledheight end
+    if depth and depth~=0 then
+      depth=delta*depth
+      if nonames then
+        chr={
+          index=index,
+          height=height,
+          depth=depth,
+          width=width,
+        }
+      else
+        chr={
+          name=description.name,
+          index=index,
+          height=height,
+          depth=depth,
+          width=width,
+        }
+      end
+    else
+      if nonames then
+        chr={
+          index=index,
+          height=height,
+          width=width,
+        }
+      else
+        chr={
+          name=description.name,
+          index=index,
+          height=height,
+          width=width,
+        }
+      end
+    end
+    local isunicode=description.unicode
+    if isunicode then
+      chr.unicode=isunicode
+      chr.tounicode=tounicode(isunicode)
+    end
+    if hasquality then
+      local ve=character.expansion_factor
+      if ve then
+        chr.expansion_factor=ve*1000 
+      end
+      local vl=character.left_protruding
+      if vl then
+        chr.left_protruding=protrusionfactor*width*vl
+      end
+      local vr=character.right_protruding
+      if vr then
+        chr.right_protruding=protrusionfactor*width*vr
+      end
+    end
+    if hasmath then
+      local vn=character.next
+      if vn then
+        chr.next=vn
+      else
+        local vv=character.vert_variants
+        if vv then
+          local t={}
+          for i=1,#vv do
+            local vvi=vv[i]
+            local s=vvi["start"]  or 0
+            local e=vvi["end"]   or 0
+            local a=vvi["advance"] or 0
+            t[i]={ 
+              ["start"]=s==0 and 0 or s*vdelta,
+              ["end"]=e==0 and 0 or e*vdelta,
+              ["advance"]=a==0 and 0 or a*vdelta,
+              ["extender"]=vvi["extender"],
+              ["glyph"]=vvi["glyph"],
+            }
+          end
+          chr.vert_variants=t
+        else
+          local hv=character.horiz_variants
+          if hv then
+            local t={}
+            for i=1,#hv do
+              local hvi=hv[i]
+              local s=hvi["start"]  or 0
+              local e=hvi["end"]   or 0
+              local a=hvi["advance"] or 0
+              t[i]={ 
+                ["start"]=s==0 and 0 or s*hdelta,
+                ["end"]=e==0 and 0 or e*hdelta,
+                ["advance"]=a==0 and 0 or a*hdelta,
+                ["extender"]=hvi["extender"],
+                ["glyph"]=hvi["glyph"],
+              }
+            end
+            chr.horiz_variants=t
+          end
+        end
+      end
+      local vi=character.vert_italic
+      if vi and vi~=0 then
+        chr.vert_italic=vi*hdelta
+      end
+      local va=character.accent
+      if va then
+        chr.top_accent=vdelta*va
+      end
+      if stackmath then
+        local mk=character.mathkerns
+        if mk then
+          local tr,tl,br,bl=mk.topright,mk.topleft,mk.bottomright,mk.bottomleft
+          chr.mathkern={ 
+            top_right=tr and mathkerns(tr,vdelta) or nil,
+            top_left=tl and mathkerns(tl,vdelta) or nil,
+            bottom_right=br and mathkerns(br,vdelta) or nil,
+            bottom_left=bl and mathkerns(bl,vdelta) or nil,
+          }
+        end
+      end
+      if hasitalics then
+        local vi=character.italic
+        if vi and vi~=0 then
+          chr.italic=vi*hdelta
+        end
+      end
+    elseif autoitalicamount then 
+      local vi=description.italic
+      if not vi then
+        local bb=description.boundingbox
+        if bb then
+          local vi=bb[3]-description.width+autoitalicamount
+          if vi>0 then 
+            chr.italic=vi*hdelta
+          end
+        else
+        end
+      elseif vi~=0 then
+        chr.italic=vi*hdelta
+      end
+    elseif hasitalics then 
+      local vi=character.italic
+      if vi and vi~=0 then
+        chr.italic=vi*hdelta
+      end
+    end
+    if haskerns then
+      local vk=character.kerns
+      if vk then
+        local s=sharedkerns[vk]
+        if not s then
+          s={}
+          for k,v in next,vk do s[k]=v*hdelta end
+          sharedkerns[vk]=s
+        end
+        chr.kerns=s
+      end
+    end
+    if hasligatures then
+      local vl=character.ligatures
+      if vl then
+        if true then
+          chr.ligatures=vl 
+        else
+          local tt={}
+          for i,l in next,vl do
+            tt[i]=l
+          end
+          chr.ligatures=tt
+        end
+      end
+    end
+    if isvirtual then
+      local vc=character.commands
+      if vc then
+        local ok=false
+        for i=1,#vc do
+          local key=vc[i][1]
+          if key=="right" or key=="down" or key=="rule" then
+            ok=true
+            break
+          end
+        end
+        if ok then
+          local tt={}
+          for i=1,#vc do
+            local ivc=vc[i]
+            local key=ivc[1]
+            if key=="right" then
+              tt[i]={ key,ivc[2]*hdelta }
+            elseif key=="down" then
+              tt[i]={ key,ivc[2]*vdelta }
+            elseif key=="rule" then
+              tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta }
+            else 
+              tt[i]=ivc 
+            end
+          end
+          chr.commands=tt
+        else
+          chr.commands=vc
+        end
+      end
+    end
+    targetcharacters[unicode]=chr
+  end
+  properties.setitalics=hasitalics
+  constructors.aftercopyingcharacters(target,tfmdata)
+  constructors.trytosharefont(target,tfmdata)
+  local vfonts=target.fonts
+if isvirtual or target.type=="virtual" or properties.virtualized then
+    properties.virtualized=true
+target.type="virtual"
+    if not vfonts or #vfonts==0 then
+      target.fonts={ { id=0 } }
+    end
+  elseif vfonts then
+    properties.virtualized=true
+    target.type="virtual"
+    if #vfonts==0 then
+      target.fonts={ { id=0 } }
+    end
+  end
+  return target
+end
+function constructors.finalize(tfmdata)
+  if tfmdata.properties and tfmdata.properties.finalized then
+    return
+  end
+  if not tfmdata.characters then
+    return nil
+  end
+  if not tfmdata.goodies then
+    tfmdata.goodies={} 
+  end
+  local parameters=tfmdata.parameters
+  if not parameters then
+    return nil
+  end
+  if not parameters.expansion then
+    parameters.expansion={
+      stretch=tfmdata.stretch or 0,
+      shrink=tfmdata.shrink or 0,
+      step=tfmdata.step  or 0,
+    }
+  end
+  if not parameters.size then
+    parameters.size=tfmdata.size
+  end
+  if not parameters.mode then
+    parameters.mode=0
+  end
+  if not parameters.width then
+    parameters.width=0
+  end
+  if not parameters.slantfactor then
+    parameters.slantfactor=tfmdata.slant or 0
+  end
+  if not parameters.extendfactor then
+    parameters.extendfactor=tfmdata.extend or 0
+  end
+  if not parameters.squeezefactor then
+    parameters.squeezefactor=tfmdata.squeeze or 0
+  end
+  local designsize=parameters.designsize
+  if designsize then
+    parameters.minsize=tfmdata.minsize or designsize
+    parameters.maxsize=tfmdata.maxsize or designsize
+  else
+    designsize=factors.pt*10
+    parameters.designsize=designsize
+    parameters.minsize=designsize
+    parameters.maxsize=designsize
+  end
+  parameters.minsize=tfmdata.minsize or parameters.designsize
+  parameters.maxsize=tfmdata.maxsize or parameters.designsize
+  if not parameters.units then
+    parameters.units=tfmdata.units or tfmdata.units_per_em or 1000
+  end
+  if not tfmdata.descriptions then
+    local descriptions={} 
+    setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end)
+    tfmdata.descriptions=descriptions
+  end
+  local properties=tfmdata.properties
+  if not properties then
+    properties={}
+    tfmdata.properties=properties
+  end
+  if not properties.virtualized then
+    properties.virtualized=tfmdata.type=="virtual"
+  end
+  if not tfmdata.properties then
+    tfmdata.properties={
+      fontname=tfmdata.fontname,
+      filename=tfmdata.filename,
+      fullname=tfmdata.fullname,
+      name=tfmdata.name,
+      psname=tfmdata.psname,
+      encodingbytes=tfmdata.encodingbytes or 1,
+      embedding=tfmdata.embedding   or "subset",
+      tounicode=tfmdata.tounicode   or 1,
+      cidinfo=tfmdata.cidinfo    or nil,
+      format=tfmdata.format    or "type1",
+      direction=tfmdata.direction   or 0,
+      writingmode=tfmdata.writingmode  or "horizontal",
+      identity=tfmdata.identity   or "horizontal",
+    }
+  end
+  if not tfmdata.resources then
+    tfmdata.resources={}
+  end
+  if not tfmdata.shared then
+    tfmdata.shared={}
+  end
+  if not properties.hasmath then
+    properties.hasmath=not tfmdata.nomath
+  end
+  tfmdata.MathConstants=nil
+  tfmdata.postprocessors=nil
+  tfmdata.fontname=nil
+  tfmdata.filename=nil
+  tfmdata.fullname=nil
+  tfmdata.name=nil 
+  tfmdata.psname=nil
+  tfmdata.encodingbytes=nil
+  tfmdata.embedding=nil
+  tfmdata.tounicode=nil
+  tfmdata.cidinfo=nil
+  tfmdata.format=nil
+  tfmdata.direction=nil
+  tfmdata.type=nil
+  tfmdata.nomath=nil
+  tfmdata.designsize=nil
+  tfmdata.size=nil
+  tfmdata.stretch=nil
+  tfmdata.shrink=nil
+  tfmdata.step=nil
+  tfmdata.slant=nil
+  tfmdata.extend=nil
+  tfmdata.squeeze=nil
+  tfmdata.mode=nil
+  tfmdata.width=nil
+  tfmdata.units=nil
+  tfmdata.units_per_em=nil
+  tfmdata.cache=nil
+  properties.finalized=true
+  return tfmdata
+end
+local hashmethods={}
+constructors.hashmethods=hashmethods
+function constructors.hashfeatures(specification) 
+  local features=specification.features
+  if features then
+    local t,n={},0
+    for category,list in sortedhash(features) do
+      if next(list) then
+        local hasher=hashmethods[category]
+        if hasher then
+          local hash=hasher(list)
+          if hash then
+            n=n+1
+            t[n]=category..":"..hash
+          end
+        end
+      end
+    end
+    if n>0 then
+      return concat(t," & ")
+    end
+  end
+  return "unknown"
+end
+hashmethods.normal=function(list)
+  local s={}
+  local n=0
+  for k,v in next,list do
+    if not k then
+    elseif k=="number" or k=="features" then
+    else
+      n=n+1
+      if type(v)=="table" then
+        local t={}
+        local m=0
+        for k,v in next,v do
+          m=m+1
+          t[m]=k..'='..tostring(v)
+        end
+        s[n]=k..'={'..concat(t,",").."}"
+      else
+        s[n]=k..'='..tostring(v)
+      end
+    end
+  end
+  if n>0 then
+    sort(s)
+    return concat(s,"+")
+  end
+end
+function constructors.hashinstance(specification,force)
+  local hash,size,fallbacks=specification.hash,specification.size,specification.fallbacks
+  if force or not hash then
+    hash=constructors.hashfeatures(specification)
+    specification.hash=hash
+  end
+  if size<1000 and designsizes[hash] then
+    size=round(constructors.scaled(size,designsizes[hash]))
+  else
+    size=round(size)
+  end
+  specification.size=size
+  if fallbacks then
+    return hash..' @ '..size..' @ '..fallbacks
+  else
+    return hash..' @ '..size
+  end
+end
+function constructors.setname(tfmdata,specification) 
+  if constructors.namemode=="specification" then
+    local specname=specification.specification
+    if specname then
+      tfmdata.properties.name=specname
+      if trace_defining then
+        report_otf("overloaded fontname %a",specname)
+      end
+    end
+  end
+end
+function constructors.checkedfilename(data)
+  local foundfilename=data.foundfilename
+  if not foundfilename then
+    local askedfilename=data.filename or ""
+    if askedfilename~="" then
+      askedfilename=resolvers.resolve(askedfilename) 
+      foundfilename=resolvers.findbinfile(askedfilename,"") or ""
+      if foundfilename=="" then
+        report_defining("source file %a is not found",askedfilename)
+        foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or ""
+        if foundfilename~="" then
+          report_defining("using source file %a due to cache mismatch",foundfilename)
+        end
+      end
+    end
+    data.foundfilename=foundfilename
+  end
+  return foundfilename
+end
+local formats=allocate()
+fonts.formats=formats
+setmetatableindex(formats,function(t,k)
+  local l=lower(k)
+  if rawget(t,k) then
+    t[k]=l
+    return l
+  end
+  return rawget(t,file.suffix(l))
+end)
+do
+  local function setindeed(mode,source,target,group,name,position)
+    local action=source[mode]
+    if not action then
+      return
+    end
+    local t=target[mode]
+    if not t then
+      report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode)
+      os.exit()
+    elseif position then
+      insert(t,position,{ name=name,action=action })
+    else
+      for i=1,#t do
+        local ti=t[i]
+        if ti.name==name then
+          ti.action=action
+          return
+        end
+      end
+      insert(t,{ name=name,action=action })
+    end
+  end
+  local function set(group,name,target,source)
+    target=target[group]
+    if not target then
+      report_defining("fatal target error in setting feature %a, group %a",name,group)
+      os.exit()
+    end
+    local source=source[group]
+    if not source then
+      report_defining("fatal source error in setting feature %a, group %a",name,group)
+      os.exit()
+    end
+    local position=source.position
+    setindeed("node",source,target,group,name,position)
+    setindeed("base",source,target,group,name,position)
+    setindeed("plug",source,target,group,name,position)
+  end
+  local function register(where,specification)
+    local name=specification.name
+    if name and name~="" then
+      local default=specification.default
+      local description=specification.description
+      local initializers=specification.initializers
+      local processors=specification.processors
+      local manipulators=specification.manipulators
+      local modechecker=specification.modechecker
+      if default then
+        where.defaults[name]=default
+      end
+      if description and description~="" then
+        where.descriptions[name]=description
+      end
+      if initializers then
+        set('initializers',name,where,specification)
+      end
+      if processors then
+        set('processors',name,where,specification)
+      end
+      if manipulators then
+        set('manipulators',name,where,specification)
+      end
+      if modechecker then
+        where.modechecker=modechecker
+      end
+    end
+  end
+  constructors.registerfeature=register
+  function constructors.getfeatureaction(what,where,mode,name)
+    what=handlers[what].features
+    if what then
+      where=what[where]
+      if where then
+        mode=where[mode]
+        if mode then
+          for i=1,#mode do
+            local m=mode[i]
+            if m.name==name then
+              return m.action
+            end
+          end
+        end
+      end
+    end
+  end
+  local newfeatures={}
+  constructors.newfeatures=newfeatures 
+  constructors.features=newfeatures
+  local function setnewfeatures(what)
+    local handler=handlers[what]
+    local features=handler.features
+    if not features then
+      local tables=handler.tables   
+      local statistics=handler.statistics 
+      features=allocate {
+        defaults={},
+        descriptions=tables and tables.features or {},
+        used=statistics and statistics.usedfeatures or {},
+        initializers={ base={},node={},plug={} },
+        processors={ base={},node={},plug={} },
+        manipulators={ base={},node={},plug={} },
+      }
+      features.register=function(specification) return register(features,specification) end
+      handler.features=features 
+    end
+    return features
+  end
+  setmetatable(newfeatures,{
+    __call=function(t,k) local v=t[k] return v end,
+    __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end,
+  })
+end
+do
+  local newhandler={}
+  constructors.handlers=newhandler 
+  constructors.newhandler=newhandler
+  local function setnewhandler(what) 
+    local handler=handlers[what]
+    if not handler then
+      handler={}
+      handlers[what]=handler
+    end
+    return handler
+  end
+  setmetatable(newhandler,{
+    __call=function(t,k) local v=t[k] return v end,
+    __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end,
+  })
+end
+do
+  local newenhancer={}
+  constructors.enhancers=newenhancer
+  constructors.newenhancer=newenhancer
+  local function setnewenhancer(format)
+    local handler=handlers[format]
+    local enhancers=handler.enhancers
+    if not enhancers then
+      local actions=allocate() 
+      local before=allocate()
+      local after=allocate()
+      local order=allocate()
+      local known={}
+      local nofsteps=0
+      local patches={ before=before,after=after }
+      local trace=false
+      local report=logs.reporter("fonts",format.." enhancing")
+      trackers.register(format..".loading",function(v) trace=v end)
+      local function enhance(name,data,filename,raw)
+        local enhancer=actions[name]
+        if enhancer then
+          if trace then
+            report("apply enhancement %a to file %a",name,filename)
+            ioflush()
+          end
+          enhancer(data,filename,raw)
+        else
+        end
+      end
+      local function apply(data,filename,raw)
+        local basename=file.basename(lower(filename))
+        if trace then
+          report("%s enhancing file %a","start",filename)
+        end
+        ioflush() 
+        for e=1,nofsteps do
+          local enhancer=order[e]
+          local b=before[enhancer]
+          if b then
+            for pattern,action in next,b do
+              if find(basename,pattern) then
+                action(data,filename,raw)
+              end
+            end
+          end
+          enhance(enhancer,data,filename,raw) 
+          local a=after[enhancer]
+          if a then
+            for pattern,action in next,a do
+              if find(basename,pattern) then
+                action(data,filename,raw)
+              end
+            end
+          end
+          ioflush() 
+        end
+        if trace then
+          report("%s enhancing file %a","stop",filename)
+        end
+        ioflush() 
+      end
+      local function register(what,action)
+        if action then
+          if actions[what] then
+          else
+            nofsteps=nofsteps+1
+            order[nofsteps]=what
+            known[what]=nofsteps
+          end
+          actions[what]=action
+        else
+          report("bad enhancer %a",what)
+        end
+      end
+      local function patch(what,where,pattern,action)
+        local pw=patches[what]
+        if pw then
+          local ww=pw[where]
+          if ww then
+            ww[pattern]=action
+          else
+            pw[where]={ [pattern]=action }
+            if not known[where] then
+              nofsteps=nofsteps+1
+              order[nofsteps]=where
+              known[where]=nofsteps
+            end
+          end
+        end
+      end
+      enhancers={
+        register=register,
+        apply=apply,
+        patch=patch,
+        report=report,
+        patches={
+          register=patch,
+          report=report,
+        },
+      }
+      handler.enhancers=enhancers
+    end
+    return enhancers
+  end
+  setmetatable(newenhancer,{
+    __call=function(t,k) local v=t[k] return v end,
+    __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end,
+  })
+end
+function constructors.checkedfeatures(what,features)
+  local defaults=handlers[what].features.defaults
+  if features and next(features) then
+    features=fastcopy(features) 
+    for key,value in next,defaults do
+      if features[key]==nil then
+        features[key]=value
+      end
+    end
+    return features
+  else
+    return fastcopy(defaults) 
+  end
+end
+function constructors.initializefeatures(what,tfmdata,features,trace,report)
+  if features and next(features) then
+    local properties=tfmdata.properties or {} 
+    local whathandler=handlers[what]
+    local whatfeatures=whathandler.features
+    local whatmodechecker=whatfeatures.modechecker
+    local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base"
+    properties.mode=mode 
+    features.mode=mode
+    local done={}
+    while true do
+      local redo=false
+      local initializers=whatfeatures.initializers[mode]
+      if initializers then
+        for i=1,#initializers do
+          local step=initializers[i]
+          local feature=step.name
+          local value=features[feature]
+          if not value then
+          elseif done[feature] then
+          else
+            local action=step.action
+            if trace then
+              report("initializing feature %a to %a for mode %a for font %a",feature,
+                value,mode,tfmdata.properties.fullname)
+            end
+            action(tfmdata,value,features) 
+            if mode~=properties.mode or mode~=features.mode then
+              if whatmodechecker then
+                properties.mode=whatmodechecker(tfmdata,features,properties.mode) 
+                features.mode=properties.mode
+              end
+              if mode~=properties.mode then
+                mode=properties.mode
+                redo=true
+              end
+            end
+            done[feature]=true
+          end
+          if redo then
+            break
+          end
+        end
+        if not redo then
+          break
+        end
+      else
+        break
+      end
+    end
+    properties.mode=mode 
+    return true
+  else
+    return false
+  end
+end
+function constructors.collectprocessors(what,tfmdata,features,trace,report)
+  local processes,nofprocesses={},0
+  if features and next(features) then
+    local properties=tfmdata.properties
+    local whathandler=handlers[what]
+    local whatfeatures=whathandler.features
+    local whatprocessors=whatfeatures.processors
+    local mode=properties.mode
+    local processors=whatprocessors[mode]
+    if processors then
+      for i=1,#processors do
+        local step=processors[i]
+        local feature=step.name
+        if features[feature] then
+          local action=step.action
+          if trace then
+            report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname)
+          end
+          if action then
+            nofprocesses=nofprocesses+1
+            processes[nofprocesses]=action
+          end
+        end
+      end
+    elseif trace then
+      report("no feature processors for mode %a for font %a",mode,properties.fullname)
+    end
+  end
+  return processes
+end
+function constructors.applymanipulators(what,tfmdata,features,trace,report)
+  if features and next(features) then
+    local properties=tfmdata.properties
+    local whathandler=handlers[what]
+    local whatfeatures=whathandler.features
+    local whatmanipulators=whatfeatures.manipulators
+    local mode=properties.mode
+    local manipulators=whatmanipulators[mode]
+    if manipulators then
+      for i=1,#manipulators do
+        local step=manipulators[i]
+        local feature=step.name
+        local value=features[feature]
+        if value then
+          local action=step.action
+          if trace then
+            report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname)
+          end
+          if action then
+            action(tfmdata,feature,value)
+          end
+        end
+      end
+    end
+  end
+end
+function constructors.addcoreunicodes(unicodes) 
+  if not unicodes then
+    unicodes={}
+  end
+  unicodes.space=0x0020
+  unicodes.hyphen=0x002D
+  unicodes.zwj=0x200D
+  unicodes.zwnj=0x200C
+  return unicodes
+end
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “font-con”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “fonts-enc” 5ff4ca50493d7c4ecea0e15c203099f0] ---
+
+if not modules then modules={} end modules ['luatex-font-enc']={
+  version=1.001,
+  comment="companion to luatex-*.tex",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+if context then
+  os.exit()
+end
+local fonts=fonts
+local encodings={}
+fonts.encodings=encodings
+encodings.agl={}
+encodings.known={}
+setmetatable(encodings.agl,{ __index=function(t,k)
+  if k=="unicodes" then
+    logs.report("fonts","loading (extended) adobe glyph list")
+    local unicodes=dofile(resolvers.findfile("font-age.lua"))
+    encodings.agl={ unicodes=unicodes }
+    return unicodes
+  else
+    return nil
+  end
+end })
+encodings.cache=containers.define("fonts","enc",encodings.version,true)
+function encodings.load(filename)
+  local name=file.removesuffix(filename)
+  local data=containers.read(encodings.cache,name)
+  if data then
+    return data
+  end
+  local vector,tag,hash,unicodes={},"",{},{}
+  local foundname=resolvers.findfile(filename,'enc')
+  if foundname and foundname~="" then
+    local ok,encoding,size=resolvers.loadbinfile(foundname)
+    if ok and encoding then
+      encoding=string.gsub(encoding,"%%(.-)\n","")
+      local unicoding=encodings.agl.unicodes
+      local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def")
+      local i=0
+      for ch in string.gmatch(vec,"/([%a%d%.]+)") do
+        if ch~=".notdef" then
+          vector[i]=ch
+          if not hash[ch] then
+            hash[ch]=i
+          else
+          end
+          local u=unicoding[ch]
+          if u then
+            unicodes[u]=i
+          end
+        end
+        i=i+1
+      end
+    end
+  end
+  local data={
+    name=name,
+    tag=tag,
+    vector=vector,
+    hash=hash,
+    unicodes=unicodes
+  }
+  return containers.write(encodings.cache,name,data)
+end
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “fonts-enc”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “font-cid” 22b0367742fb253deef84ef7ccf5e8de] ---
+
+if not modules then modules={} end modules ['font-cid']={
+  version=1.001,
+  comment="companion to font-ini.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+local format,match,lower=string.format,string.match,string.lower
+local tonumber=tonumber
+local P,S,R,C,V,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.match
+local fonts,logs,trackers=fonts,logs,trackers
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local report_otf=logs.reporter("fonts","otf loading")
+local cid={}
+fonts.cid=cid
+local cidmap={}
+local cidmax=10
+local number=C(R("09","af","AF")^1)
+local space=S(" \n\r\t")
+local spaces=space^0
+local period=P(".")
+local periods=period*period
+local name=P("/")*C((1-space)^1)
+local unicodes,names={},{} 
+local function do_one(a,b)
+  unicodes[tonumber(a)]=tonumber(b,16)
+end
+local function do_range(a,b,c)
+  c=tonumber(c,16)
+  for i=tonumber(a),tonumber(b) do
+    unicodes[i]=c
+    c=c+1
+  end
+end
+local function do_name(a,b)
+  names[tonumber(a)]=b
+end
+local grammar=P { "start",
+  start=number*spaces*number*V("series"),
+  series=(spaces*(V("one")+V("range")+V("named")))^1,
+  one=(number*spaces*number)/do_one,
+  range=(number*periods*number*spaces*number)/do_range,
+  named=(number*spaces*name)/do_name
+}
+local function loadcidfile(filename)
+  local data=io.loaddata(filename)
+  if data then
+    unicodes,names={},{}
+    lpegmatch(grammar,data)
+    local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$")
+    return {
+      supplement=supplement,
+      registry=registry,
+      ordering=ordering,
+      filename=filename,
+      unicodes=unicodes,
+      names=names,
+    }
+  end
+end
+cid.loadfile=loadcidfile 
+local template="%s-%s-%s.cidmap"
+local function locate(registry,ordering,supplement)
+  local filename=format(template,registry,ordering,supplement)
+  local hashname=lower(filename)
+  local found=cidmap[hashname]
+  if not found then
+    if trace_loading then
+      report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename)
+    end
+    local fullname=resolvers.findfile(filename,'cid') or ""
+    if fullname~="" then
+      found=loadcidfile(fullname)
+      if found then
+        if trace_loading then
+          report_otf("using cidmap file %a",filename)
+        end
+        cidmap[hashname]=found
+        found.usedname=file.basename(filename)
+      end
+    end
+  end
+  return found
+end
+function cid.getmap(specification)
+  if not specification then
+    report_otf("invalid cidinfo specification, table expected")
+    return
+  end
+  local registry=specification.registry
+  local ordering=specification.ordering
+  local supplement=specification.supplement
+  local filename=format(registry,ordering,supplement)
+  local lowername=lower(filename)
+  local found=cidmap[lowername]
+  if found then
+    return found
+  end
+  if ordering=="Identity" then
+    local found={
+      supplement=supplement,
+      registry=registry,
+      ordering=ordering,
+      filename=filename,
+      unicodes={},
+      names={},
+    }
+    cidmap[lowername]=found
+    return found
+  end
+  if trace_loading then
+    report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement)
+  end
+  found=locate(registry,ordering,supplement)
+  if not found then
+    local supnum=tonumber(supplement)
+    local cidnum=nil
+    if supnum<cidmax then
+      for s=supnum+1,cidmax do
+        local c=locate(registry,ordering,s)
+        if c then
+          found,cidnum=c,s
+          break
+        end
+      end
+    end
+    if not found and supnum>0 then
+      for s=supnum-1,0,-1 do
+        local c=locate(registry,ordering,s)
+        if c then
+          found,cidnum=c,s
+          break
+        end
+      end
+    end
+    registry=lower(registry)
+    ordering=lower(ordering)
+    if found and cidnum>0 then
+      for s=0,cidnum-1 do
+        local filename=format(template,registry,ordering,s)
+        if not cidmap[filename] then
+          cidmap[filename]=found
+        end
+      end
+    end
+  end
+  return found
+end
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “font-cid”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “font-map” 2c03dc61afabb5887ef18a88e6ec86bd] ---
+
+if not modules then modules={} end modules ['font-map']={
+  version=1.001,
+  comment="companion to font-ini.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+local tonumber,next,type=tonumber,next,type
+local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower
+local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match
+local formatters=string.formatters
+local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
+local rshift=bit32.rshift
+local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end)
+local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end)
+local report_fonts=logs.reporter("fonts","loading")
+local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end)
+local fonts=fonts or {}
+local mappings=fonts.mappings or {}
+fonts.mappings=mappings
+local allocate=utilities.storage.allocate
+local hex=R("AF","af","09")
+local hexfour=(hex*hex*hex^-2)/function(s) return tonumber(s,16) end
+local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end
+local dec=(R("09")^1)/tonumber
+local period=P(".")
+local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true)) 
+local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true)) 
+local index=P("index")*dec*Cc(false)
+local parser=unicode+ucode+index
+local parsers={}
+local function makenameparser(str)
+  if not str or str=="" then
+    return parser
+  else
+    local p=parsers[str]
+    if not p then
+      p=P(str)*period*dec*Cc(false)
+      parsers[str]=p
+    end
+    return p
+  end
+end
+local f_single=formatters["%04X"]
+local f_double=formatters["%04X%04X"]
+local function tounicode16(unicode)
+  if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then
+    return f_single(unicode)
+  else
+    unicode=unicode-0x10000
+    return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+  end
+end
+local function tounicode16sequence(unicodes)
+  local t={}
+  for l=1,#unicodes do
+    local u=unicodes[l]
+    if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then
+      t[l]=f_single(u)
+    else
+      u=u-0x10000
+      t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
+    end
+  end
+  return concat(t)
+end
+local unknown=f_single(0xFFFD)
+local hash={}
+local conc={}
+table.setmetatableindex(hash,function(t,k)
+  if type(k)=="table" then
+    local n=#k
+    for l=1,n do
+      conc[l]=hash[k[l]]
+    end
+    return concat(conc,"",1,n)
+  end
+  local v
+  if k>=0x00E000 and k<=0x00F8FF then
+    v=unknown
+  elseif k>=0x0F0000 and k<=0x0FFFFF then
+    v=unknown
+  elseif k>=0x100000 and k<=0x10FFFF then
+    v=unknown
+  elseif k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then
+    v=f_single(k)
+  else
+    k=k-0x10000
+    v=f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+  end
+  t[k]=v
+  return v
+end)
+local function tounicode(unicode)
+  return hash[unicode]
+end
+local function fromunicode16(str)
+  if #str==4 then
+    return tonumber(str,16)
+  else
+    local l,r=match(str,"(....)(....)")
+    return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00
+  end
+end
+mappings.makenameparser=makenameparser
+mappings.tounicode=tounicode
+mappings.tounicode16=tounicode16
+mappings.tounicode16sequence=tounicode16sequence
+mappings.fromunicode16=fromunicode16
+local ligseparator=P("_")
+local varseparator=P(".")
+local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0)
+do
+  local overloads={
+    IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 },
+    ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 },
+    ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 },
+    fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 },
+    fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 },
+    ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 },
+    ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 },
+    fj={ name="f_j",unicode={ 0x66,0x6A } },
+    fk={ name="f_k",unicode={ 0x66,0x6B } },
+  }
+  local o=allocate {}
+  for k,v in next,overloads do
+    local name=v.name
+    local mess=v.mess
+    if name then
+      o[name]=v
+    end
+    if mess then
+      o[mess]=v
+    end
+    o[k]=v
+  end
+  mappings.overloads=o
+end
+function mappings.addtounicode(data,filename,checklookups,forceligatures)
+  local resources=data.resources
+  local unicodes=resources.unicodes
+  if not unicodes then
+    if trace_mapping then
+      report_fonts("no unicode list, quitting tounicode for %a",filename)
+    end
+    return
+  end
+  local properties=data.properties
+  local descriptions=data.descriptions
+  local overloads=mappings.overloads
+  unicodes['space']=unicodes['space'] or 32
+  unicodes['hyphen']=unicodes['hyphen'] or 45
+  unicodes['zwj']=unicodes['zwj']  or 0x200D
+  unicodes['zwnj']=unicodes['zwnj']  or 0x200C
+  local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 
+  local unicodevector=fonts.encodings.agl.unicodes or {} 
+  local contextvector=fonts.encodings.agl.ctxcodes or {} 
+  local missing={}
+  local nofmissing=0
+  local oparser=nil
+  local cidnames=nil
+  local cidcodes=nil
+  local cidinfo=properties.cidinfo
+  local usedmap=cidinfo and fonts.cid.getmap(cidinfo)
+  local uparser=makenameparser() 
+  if usedmap then
+     oparser=usedmap and makenameparser(cidinfo.ordering)
+     cidnames=usedmap.names
+     cidcodes=usedmap.unicodes
+  end
+  local ns=0
+  local nl=0
+  local dlist=sortedkeys(descriptions)
+  for i=1,#dlist do
+    local du=dlist[i]
+    local glyph=descriptions[du]
+    local name=glyph.name
+    if name then
+      local overload=overloads[name] or overloads[du]
+      if overload then
+        glyph.unicode=overload.unicode
+      else
+        local gu=glyph.unicode 
+        if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then
+          local unicode=unicodevector[name] or contextvector[name]
+          if unicode then
+            glyph.unicode=unicode
+            ns=ns+1
+          end
+          if (not unicode) and usedmap then
+            local foundindex=lpegmatch(oparser,name)
+            if foundindex then
+              unicode=cidcodes[foundindex] 
+              if unicode then
+                glyph.unicode=unicode
+                ns=ns+1
+              else
+                local reference=cidnames[foundindex] 
+                if reference then
+                  local foundindex=lpegmatch(oparser,reference)
+                  if foundindex then
+                    unicode=cidcodes[foundindex]
+                    if unicode then
+                      glyph.unicode=unicode
+                      ns=ns+1
+                    end
+                  end
+                  if not unicode or unicode=="" then
+                    local foundcodes,multiple=lpegmatch(uparser,reference)
+                    if foundcodes then
+                      glyph.unicode=foundcodes
+                      if multiple then
+                        nl=nl+1
+                        unicode=true
+                      else
+                        ns=ns+1
+                        unicode=foundcodes
+                      end
+                    end
+                  end
+                end
+              end
+            end
+          end
+          if not unicode or unicode=="" then
+            local split=lpegmatch(namesplitter,name)
+            local nsplit=split and #split or 0 
+            if nsplit==0 then
+            elseif nsplit==1 then
+              local base=split[1]
+              local u=unicodes[base] or unicodevector[base] or contextvector[name]
+              if not u then
+              elseif type(u)=="table" then
+                if u[1]<private then
+                  unicode=u
+                  glyph.unicode=unicode
+                end
+              elseif u<private then
+                unicode=u
+                glyph.unicode=unicode
+              end
+            else
+              local t,n={},0
+              for l=1,nsplit do
+                local base=split[l]
+                local u=unicodes[base] or unicodevector[base] or contextvector[name]
+                if not u then
+                  break
+                elseif type(u)=="table" then
+                  if u[1]>=private then
+                    break
+                  end
+                  n=n+1
+                  t[n]=u[1]
+                else
+                  if u>=private then
+                    break
+                  end
+                  n=n+1
+                  t[n]=u
+                end
+              end
+              if n>0 then
+                if n==1 then
+                  unicode=t[1]
+                else
+                  unicode=t
+                end
+                glyph.unicode=unicode
+              end
+            end
+            nl=nl+1
+          end
+          if not unicode or unicode=="" then
+            local foundcodes,multiple=lpegmatch(uparser,name)
+            if foundcodes then
+              glyph.unicode=foundcodes
+              if multiple then
+                nl=nl+1
+                unicode=true
+              else
+                ns=ns+1
+                unicode=foundcodes
+              end
+            end
+          end
+          local r=overloads[unicode]
+          if r then
+            unicode=r.unicode
+            glyph.unicode=unicode
+          end
+          if not unicode then
+            missing[du]=true
+            nofmissing=nofmissing+1
+          end
+        end
+      end
+    else
+      local overload=overloads[du]
+      if overload then
+        glyph.unicode=overload.unicode
+      end
+    end
+  end
+  if type(checklookups)=="function" then
+    checklookups(data,missing,nofmissing)
+  end
+  local unicoded=0
+  local collected=fonts.handlers.otf.readers.getcomponents(data) 
+  local function resolve(glyph,u)
+    local n=#u
+    for i=1,n do
+      if u[i]>private then
+        n=0
+        break
+      end
+    end
+    if n>0 then
+      if n>1 then
+        glyph.unicode=u
+      else
+        glyph.unicode=u[1]
+      end
+      unicoded=unicoded+1
+    end
+  end
+  if not collected then
+  elseif forceligatures or force_ligatures then
+    for i=1,#dlist do
+      local du=dlist[i]
+      if du>=private or (du>=0xE000 and du<=0xF8FF) then
+        local u=collected[du] 
+        if u then
+          resolve(descriptions[du],u)
+        end
+      end
+    end
+  else
+    for i=1,#dlist do
+      local du=dlist[i]
+      if du>=private or (du>=0xE000 and du<=0xF8FF) then
+        local glyph=descriptions[du]
+        if glyph.class=="ligature" and not glyph.unicode then
+          local u=collected[du] 
+          if u then
+             resolve(glyph,u)
+          end
+        end
+      end
+    end
+  end
+  if trace_mapping and unicoded>0 then
+    report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded)
+  end
+  if trace_mapping then
+    for i=1,#dlist do
+      local du=dlist[i]
+      local glyph=descriptions[du]
+      local name=glyph.name or "-"
+      local index=glyph.index or 0
+      local unicode=glyph.unicode
+      if unicode then
+        if type(unicode)=="table" then
+          local unicodes={}
+          for i=1,#unicode do
+            unicodes[i]=formatters("%U",unicode[i])
+          end
+          report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes)
+        else
+          report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode)
+        end
+      else
+        report_fonts("internal slot %U, name %a, unicode %U",index,name,du)
+      end
+    end
+  end
+  if trace_loading and (ns>0 or nl>0) then
+    report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns)
+  end
+end
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “font-map”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “font-vfc” 237aff1862009b7850653c2098473bd4] ---
+
+if not modules then modules={} end modules ['font-vfc']={
+  version=1.001,
+  comment="companion to font-ini.mkiv and hand-ini.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+local select=select
+local insert=table.insert
+local fonts=fonts
+local helpers=fonts.helpers
+local setmetatableindex=table.setmetatableindex
+local makeweak=table.makeweak
+local push={ "push" }
+local pop={ "pop" }
+local dummy={ "comment" }
+function helpers.prependcommands(commands,...)
+  insert(commands,1,push)
+  for i=select("#",...),1,-1 do
+    local s=select(i,...)
+    if s then
+      insert(commands,1,s)
+    end
+  end
+  insert(commands,pop)
+  return commands
+end
+function helpers.appendcommands(commands,...)
+  insert(commands,1,push)
+  insert(commands,pop)
+  for i=1,select("#",...) do
+    local s=select(i,...)
+    if s then
+      insert(commands,s)
+    end
+  end
+  return commands
+end
+local char=setmetatableindex(function(t,k)
+  local v={ "slot",0,k }
+  t[k]=v
+  return v
+end)
+local right=setmetatableindex(function(t,k)
+  local v={ "right",k }
+  t[k]=v
+  return v
+end)
+local left=setmetatableindex(function(t,k)
+  local v={ "right",-k }
+  t[k]=v
+  return v
+end)
+local down=setmetatableindex(function(t,k)
+  local v={ "down",k }
+  t[k]=v
+  return v
+end)
+local up=setmetatableindex(function(t,k)
+  local v={ "down",-k }
+  t[k]=v
+  return v
+end)
+helpers.commands=utilities.storage.allocate {
+  char=char,
+  right=right,
+  left=left,
+  down=down,
+  up=up,
+  push=push,
+  pop=pop,
+  dummy=dummy,
+}
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “font-vfc”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “font-otr” 4a1dae571a43d7cb8afce7e906df89c6] ---
+
+if not modules then modules={} end modules ['font-otr']={
+  version=1.001,
+  comment="companion to font-ini.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+local next,type,tonumber=next,type,tonumber
+local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub
+local floor,round=math.floor,math.round
+local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt
+local lpegmatch=lpeg.match
+local rshift=bit32.rshift
+local setmetatableindex=table.setmetatableindex
+local formatters=string.formatters
+local sortedkeys=table.sortedkeys
+local sortedhash=table.sortedhash
+local stripstring=string.nospaces
+local utf16_to_utf8_be=utf.utf16_to_utf8_be
+local report=logs.reporter("otf reader")
+local trace_cmap=false 
+local trace_cmap_detail=false
+fonts=fonts or {}
+local handlers=fonts.handlers or {}
+fonts.handlers=handlers
+local otf=handlers.otf or {}
+handlers.otf=otf
+local readers=otf.readers or {}
+otf.readers=readers
+local streamreader=utilities.files  
+local streamwriter=utilities.files
+readers.streamreader=streamreader
+readers.streamwriter=streamwriter
+local openfile=streamreader.open
+local closefile=streamreader.close
+local setposition=streamreader.setposition
+local skipshort=streamreader.skipshort
+local readbytes=streamreader.readbytes
+local readstring=streamreader.readstring
+local readbyte=streamreader.readcardinal1 
+local readushort=streamreader.readcardinal2 
+local readuint=streamreader.readcardinal3 
+local readulong=streamreader.readcardinal4
+local readshort=streamreader.readinteger2  
+local readlong=streamreader.readinteger4  
+local readfixed=streamreader.readfixed4
+local read2dot14=streamreader.read2dot14   
+local readfword=readshort          
+local readufword=readushort         
+local readoffset=readushort
+local readcardinaltable=streamreader.readcardinaltable
+local readintegertable=streamreader.readintegertable
+function streamreader.readtag(f)
+  return lower(stripstring(readstring(f,4)))
+end
+local short=2
+local ushort=2
+local ulong=4
+directives.register("fonts.streamreader",function()
+  streamreader=utilities.streams
+  openfile=streamreader.open
+  closefile=streamreader.close
+  setposition=streamreader.setposition
+  skipshort=streamreader.skipshort
+  readbytes=streamreader.readbytes
+  readstring=streamreader.readstring
+  readbyte=streamreader.readcardinal1
+  readushort=streamreader.readcardinal2
+  readuint=streamreader.readcardinal3
+  readulong=streamreader.readcardinal4
+  readshort=streamreader.readinteger2
+  readlong=streamreader.readinteger4
+  readfixed=streamreader.readfixed4
+  read2dot14=streamreader.read2dot14
+  readfword=readshort
+  readufword=readushort
+  readoffset=readushort
+  readcardinaltable=streamreader.readcardinaltable
+  readintegertable=streamreader.readintegertable
+  function streamreader.readtag(f)
+    return lower(stripstring(readstring(f,4)))
+  end
+end)
+local function readlongdatetime(f)
+  local a,b,c,d,e,f,g,h=readbytes(f,8)
+  return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+end
+local tableversion=0.004
+readers.tableversion=tableversion
+local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+local reservednames={ [0]="copyright",
+  "family",
+  "subfamily",
+  "uniqueid",
+  "fullname",
+  "version",
+  "postscriptname",
+  "trademark",
+  "manufacturer",
+  "designer",
+  "description",
+  "vendorurl",
+  "designerurl",
+  "license",
+  "licenseurl",
+  "reserved",
+  "typographicfamily",
+  "typographicsubfamily",
+  "compatiblefullname",
+  "sampletext",
+  "cidfindfontname",
+  "wwsfamily",
+  "wwssubfamily",
+  "lightbackgroundpalette",
+  "darkbackgroundpalette",
+  "variationspostscriptnameprefix",
+}
+local platforms={ [0]="unicode",
+  "macintosh",
+  "iso",
+  "windows",
+  "custom",
+}
+local encodings={
+  unicode={ [0]="unicode 1.0 semantics",
+    "unicode 1.1 semantics",
+    "iso/iec 10646",
+    "unicode 2.0 bmp",
+    "unicode 2.0 full",
+    "unicode variation sequences",
+    "unicode full repertoire",
+  },
+  macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian",
+    "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada",
+    "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian",
+    "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi",
+    "uninterpreted",
+  },
+  iso={ [0]="7-bit ascii",
+    "iso 10646",
+    "iso 8859-1",
+  },
+  windows={ [0]="symbol",
+    "unicode bmp",
+    "shiftjis",
+    "prc",
+    "big5",
+    "wansung",
+    "johab",
+    "reserved 7",
+    "reserved 8",
+    "reserved 9",
+    "unicode ucs-4",
+  },
+  custom={
+  }
+}
+local decoders={
+  unicode={},
+  macintosh={},
+  iso={},
+  windows={
+    ["unicode semantics"]=utf16_to_utf8_be,
+    ["unicode bmp"]=utf16_to_utf8_be,
+    ["unicode full"]=utf16_to_utf8_be,
+    ["unicode 1.0 semantics"]=utf16_to_utf8_be,
+    ["unicode 1.1 semantics"]=utf16_to_utf8_be,
+    ["unicode 2.0 bmp"]=utf16_to_utf8_be,
+    ["unicode 2.0 full"]=utf16_to_utf8_be,
+    ["unicode variation sequences"]=utf16_to_utf8_be,
+    ["unicode full repertoire"]=utf16_to_utf8_be,
+  },
+  custom={},
+}
+local languages={
+  unicode={
+    [ 0]="english",
+  },
+  macintosh={
+    [ 0]="english",
+  },
+  iso={},
+  windows={
+    [0x0409]="english - united states",
+  },
+  custom={},
+}
+local standardromanencoding={ [0]=
+  "notdef",".null","nonmarkingreturn","space","exclam","quotedbl",
+  "numbersign","dollar","percent","ampersand","quotesingle","parenleft",
+  "parenright","asterisk","plus","comma","hyphen","period","slash",
+  "zero","one","two","three","four","five","six","seven","eight",
+  "nine","colon","semicolon","less","equal","greater","question","at",
+  "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O",
+  "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft",
+  "backslash","bracketright","asciicircum","underscore","grave","a","b",
+  "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q",
+  "r","s","t","u","v","w","x","y","z","braceleft","bar",
+  "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute",
+  "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex",
+  "adieresis","atilde","aring","ccedilla","eacute","egrave",
+  "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis",
+  "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute",
+  "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling",
+  "section","bullet","paragraph","germandbls","registered","copyright",
+  "trademark","acute","dieresis","notequal","AE","Oslash","infinity",
+  "plusminus","lessequal","greaterequal","yen","mu","partialdiff",
+  "summation","product","pi","integral","ordfeminine","ordmasculine",
+  "Omega","ae","oslash","questiondown","exclamdown","logicalnot",
+  "radical","florin","approxequal","Delta","guillemotleft",
+  "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde",
+  "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright",
+  "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis",
+  "fraction","currency","guilsinglleft","guilsinglright","fi","fl",
+  "daggerdbl","periodcentered","quotesinglbase","quotedblbase",
+  "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave",
+  "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex",
+  "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi",
+  "circumflex","tilde","macron","breve","dotaccent","ring","cedilla",
+  "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron",
+  "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn",
+  "thorn","minus","multiply","onesuperior","twosuperior","threesuperior",
+  "onehalf","onequarter","threequarters","franc","Gbreve","gbreve",
+  "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron",
+  "dcroat",
+}
+local weights={
+  [100]="thin",
+  [200]="extralight",
+  [300]="light",
+  [400]="normal",
+  [500]="medium",
+  [600]="semibold",
+  [700]="bold",
+  [800]="extrabold",
+  [900]="black",
+}
+local widths={
+  [1]="ultracondensed",
+  [2]="extracondensed",
+  [3]="condensed",
+  [4]="semicondensed",
+  [5]="normal",
+  [6]="semiexpanded",
+  [7]="expanded",
+  [8]="extraexpanded",
+  [9]="ultraexpanded",
+}
+setmetatableindex(weights,function(t,k)
+  local r=floor((k+50)/100)*100
+  local v=(r>900 and "black") or rawget(t,r) or "normal"
+  return v
+end)
+setmetatableindex(widths,function(t,k)
+  return "normal"
+end)
+local panoseweights={
+  [ 0]="normal",
+  [ 1]="normal",
+  [ 2]="verylight",
+  [ 3]="light",
+  [ 4]="thin",
+  [ 5]="book",
+  [ 6]="medium",
+  [ 7]="demi",
+  [ 8]="bold",
+  [ 9]="heavy",
+  [10]="black",
+}
+local panosewidths={
+  [ 0]="normal",
+  [ 1]="normal",
+  [ 2]="normal",
+  [ 3]="normal",
+  [ 4]="normal",
+  [ 5]="expanded",
+  [ 6]="condensed",
+  [ 7]="veryexpanded",
+  [ 8]="verycondensed",
+  [ 9]="monospaced",
+}
+local helpers={}
+readers.helpers=helpers
+local function gotodatatable(f,fontdata,tag,criterium)
+  if criterium and f then
+    local datatable=fontdata.tables[tag]
+    if datatable then
+      local tableoffset=datatable.offset
+      setposition(f,tableoffset)
+      return tableoffset
+    end
+  end
+end
+local function reportskippedtable(f,fontdata,tag,criterium)
+  if criterium and f then
+    local datatable=fontdata.tables[tag]
+    if datatable then
+      report("loading of table %a skipped",tag)
+    end
+  end
+end
+local function setvariabledata(fontdata,tag,data)
+  local variabledata=fontdata.variabledata
+  if variabledata then
+    variabledata[tag]=data
+  else
+    fontdata.variabledata={ [tag]=data }
+  end
+end
+helpers.gotodatatable=gotodatatable
+helpers.setvariabledata=setvariabledata
+helpers.reportskippedtable=reportskippedtable
+local platformnames={
+  postscriptname=true,
+  fullname=true,
+  family=true,
+  subfamily=true,
+  typographicfamily=true,
+  typographicsubfamily=true,
+  compatiblefullname=true,
+}
+function readers.name(f,fontdata,specification)
+  local tableoffset=gotodatatable(f,fontdata,"name",true)
+  if tableoffset then
+    local format=readushort(f)
+    local nofnames=readushort(f)
+    local offset=readushort(f)
+    local start=tableoffset+offset
+    local namelists={
+      unicode={},
+      windows={},
+      macintosh={},
+    }
+    for i=1,nofnames do
+      local platform=platforms[readushort(f)]
+      if platform then
+        local namelist=namelists[platform]
+        if namelist then
+          local encoding=readushort(f)
+          local language=readushort(f)
+          local encodings=encodings[platform]
+          local languages=languages[platform]
+          if encodings and languages then
+            local encoding=encodings[encoding]
+            local language=languages[language]
+            if encoding and language then
+              local index=readushort(f)
+              local name=reservednames[index]
+              namelist[#namelist+1]={
+                platform=platform,
+                encoding=encoding,
+                language=language,
+                name=name,
+                index=index,
+                length=readushort(f),
+                offset=start+readushort(f),
+              }
+            else
+              skipshort(f,3)
+            end
+          else
+            skipshort(f,3)
+          end
+        else
+          skipshort(f,5)
+        end
+      else
+        skipshort(f,5)
+      end
+    end
+    local names={}
+    local done={}
+    local extras={}
+    local function filter(platform,e,l)
+      local namelist=namelists[platform]
+      for i=1,#namelist do
+        local name=namelist[i]
+        local nametag=name.name
+        local index=name.index
+        if not done[nametag or i] then
+          local encoding=name.encoding
+          local language=name.language
+          if (not e or encoding==e) and (not l or language==l) then
+            setposition(f,name.offset)
+            local content=readstring(f,name.length)
+            local decoder=decoders[platform]
+            if decoder then
+              decoder=decoder[encoding]
+            end
+            if decoder then
+              content=decoder(content)
+            end
+            if nametag then
+              names[nametag]={
+                content=content,
+                platform=platform,
+                encoding=encoding,
+                language=language,
+              }
+            end
+            extras[index]=content
+            done[nametag or i]=true
+          end
+        end
+      end
+    end
+    filter("windows","unicode bmp","english - united states")
+    filter("macintosh","roman","english")
+    filter("windows")
+    filter("macintosh")
+    filter("unicode")
+    fontdata.names=names
+    fontdata.extras=extras
+    if specification.platformnames then
+      local collected={}
+      for platform,namelist in next,namelists do
+        local filtered=false
+        for i=1,#namelist do
+          local entry=namelist[i]
+          local name=entry.name
+          if platformnames[name] then
+            setposition(f,entry.offset)
+            local content=readstring(f,entry.length)
+            local encoding=entry.encoding
+            local decoder=decoders[platform]
+            if decoder then
+              decoder=decoder[encoding]
+            end
+            if decoder then
+              content=decoder(content)
+            end
+            if filtered then
+              filtered[name]=content
+            else
+              filtered={ [name]=content }
+            end
+          end
+        end
+        if filtered then
+          collected[platform]=filtered
+        end
+      end
+      fontdata.platformnames=collected
+    end
+  else
+    fontdata.names={}
+  end
+end
+local validutf=lpeg.patterns.validutf8
+local function getname(fontdata,key)
+  local names=fontdata.names
+  if names then
+    local value=names[key]
+    if value then
+      local content=value.content
+      return lpegmatch(validutf,content) and content or nil
+    end
+  end
+end
+readers["os/2"]=function(f,fontdata)
+  local tableoffset=gotodatatable(f,fontdata,"os/2",true)
+  if tableoffset then
+    local version=readushort(f)
+    local windowsmetrics={
+      version=version,
+      averagewidth=readshort(f),
+      weightclass=readushort(f),
+      widthclass=readushort(f),
+      fstype=readushort(f),
+      subscriptxsize=readshort(f),
+      subscriptysize=readshort(f),
+      subscriptxoffset=readshort(f),
+      subscriptyoffset=readshort(f),
+      superscriptxsize=readshort(f),
+      superscriptysize=readshort(f),
+      superscriptxoffset=readshort(f),
+      superscriptyoffset=readshort(f),
+      strikeoutsize=readshort(f),
+      strikeoutpos=readshort(f),
+      familyclass=readshort(f),
+      panose={ readbytes(f,10) },
+      unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) },
+      vendor=readstring(f,4),
+      fsselection=readushort(f),
+      firstcharindex=readushort(f),
+      lastcharindex=readushort(f),
+      typoascender=readshort(f),
+      typodescender=readshort(f),
+      typolinegap=readshort(f),
+      winascent=readushort(f),
+      windescent=readushort(f),
+    }
+    if version>=1 then
+      windowsmetrics.codepageranges={ readulong(f),readulong(f) }
+    end
+    if version>=3 then
+      windowsmetrics.xheight=readshort(f)
+      windowsmetrics.capheight=readshort(f)
+      windowsmetrics.defaultchar=readushort(f)
+      windowsmetrics.breakchar=readushort(f)
+    end
+    windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass]
+    windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass]
+    windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]]
+    windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]]
+    fontdata.windowsmetrics=windowsmetrics
+  else
+    fontdata.windowsmetrics={}
+  end
+end
+readers.head=function(f,fontdata)
+  local tableoffset=gotodatatable(f,fontdata,"head",true)
+  if tableoffset then
+    local fontheader={
+      version=readfixed(f),
+      revision=readfixed(f),
+      checksum=readulong(f),
+      magic=readulong(f),
+      flags=readushort(f),
+      units=readushort(f),
+      created=readlongdatetime(f),
+      modified=readlongdatetime(f),
+      xmin=readshort(f),
+      ymin=readshort(f),
+      xmax=readshort(f),
+      ymax=readshort(f),
+      macstyle=readushort(f),
+      smallpixels=readushort(f),
+      directionhint=readshort(f),
+      indextolocformat=readshort(f),
+      glyphformat=readshort(f),
+    }
+    fontdata.fontheader=fontheader
+  else
+    fontdata.fontheader={}
+  end
+  fontdata.nofglyphs=0
+end
+readers.hhea=function(f,fontdata,specification)
+  local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details)
+  if tableoffset then
+    fontdata.horizontalheader={
+      version=readfixed(f),
+      ascender=readfword(f),
+      descender=readfword(f),
+      linegap=readfword(f),
+      maxadvancewidth=readufword(f),
+      minleftsidebearing=readfword(f),
+      minrightsidebearing=readfword(f),
+      maxextent=readfword(f),
+      caretsloperise=readshort(f),
+      caretsloperun=readshort(f),
+      caretoffset=readshort(f),
+      reserved_1=readshort(f),
+      reserved_2=readshort(f),
+      reserved_3=readshort(f),
+      reserved_4=readshort(f),
+      metricdataformat=readshort(f),
+      nofmetrics=readushort(f),
+    }
+  else
+    fontdata.horizontalheader={
+      nofmetrics=0,
+    }
+  end
+end
+readers.vhea=function(f,fontdata,specification)
+  local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details)
+  if tableoffset then
+    fontdata.verticalheader={
+      version=readfixed(f),
+      ascender=readfword(f),
+      descender=readfword(f),
+      linegap=readfword(f),
+      maxadvanceheight=readufword(f),
+      mintopsidebearing=readfword(f),
+      minbottomsidebearing=readfword(f),
+      maxextent=readfword(f),
+      caretsloperise=readshort(f),
+      caretsloperun=readshort(f),
+      caretoffset=readshort(f),
+      reserved_1=readshort(f),
+      reserved_2=readshort(f),
+      reserved_3=readshort(f),
+      reserved_4=readshort(f),
+      metricdataformat=readshort(f),
+      nofmetrics=readushort(f),
+    }
+  else
+    fontdata.verticalheader={
+      nofmetrics=0,
+    }
+  end
+end
+readers.maxp=function(f,fontdata,specification)
+  local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details)
+  if tableoffset then
+    local version=readfixed(f)
+    local nofglyphs=readushort(f)
+    fontdata.nofglyphs=nofglyphs
+    if version==0.5 then
+      fontdata.maximumprofile={
+        version=version,
+        nofglyphs=nofglyphs,
+      }
+    elseif version==1.0 then
+      fontdata.maximumprofile={
+        version=version,
+        nofglyphs=nofglyphs,
+        points=readushort(f),
+        contours=readushort(f),
+        compositepoints=readushort(f),
+        compositecontours=readushort(f),
+        zones=readushort(f),
+        twilightpoints=readushort(f),
+        storage=readushort(f),
+        functiondefs=readushort(f),
+        instructiondefs=readushort(f),
+        stackelements=readushort(f),
+        sizeofinstructions=readushort(f),
+        componentelements=readushort(f),
+        componentdepth=readushort(f),
+      }
+    else
+      fontdata.maximumprofile={
+        version=version,
+        nofglyphs=0,
+      }
+    end
+  end
+end
+readers.hmtx=function(f,fontdata,specification)
+  local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs)
+  if tableoffset then
+    local horizontalheader=fontdata.horizontalheader
+    local nofmetrics=horizontalheader.nofmetrics
+    local glyphs=fontdata.glyphs
+    local nofglyphs=fontdata.nofglyphs
+    local width=0 
+    local leftsidebearing=0
+    for i=0,nofmetrics-1 do
+      local glyph=glyphs[i]
+      width=readshort(f)
+      leftsidebearing=readshort(f)
+      if width~=0 then
+        glyph.width=width
+      end
+    end
+    for i=nofmetrics,nofglyphs-1 do
+      local glyph=glyphs[i]
+      if width~=0 then
+        glyph.width=width
+      end
+    end
+  end
+end
+readers.vmtx=function(f,fontdata,specification)
+  local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs)
+  if tableoffset then
+    local verticalheader=fontdata.verticalheader
+    local nofmetrics=verticalheader.nofmetrics
+    local glyphs=fontdata.glyphs
+    local nofglyphs=fontdata.nofglyphs
+    local vheight=0
+    local vdefault=verticalheader.ascender+verticalheader.descender
+    local topsidebearing=0
+    for i=0,nofmetrics-1 do
+      local glyph=glyphs[i]
+      vheight=readshort(f)
+      topsidebearing=readshort(f)
+      if vheight~=0 and vheight~=vdefault then
+        glyph.vheight=vheight
+      end
+    end
+    for i=nofmetrics,nofglyphs-1 do
+      local glyph=glyphs[i]
+      if vheight~=0 and vheight~=vdefault then
+        glyph.vheight=vheight
+      end
+    end
+  end
+end
+readers.vorg=function(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"vorg",specification.glyphs)
+end
+readers.post=function(f,fontdata,specification)
+  local tableoffset=gotodatatable(f,fontdata,"post",true)
+  if tableoffset then
+    local version=readfixed(f)
+    fontdata.postscript={
+      version=version,
+      italicangle=round(1000*readfixed(f))/1000,
+      underlineposition=readfword(f),
+      underlinethickness=readfword(f),
+      monospaced=readulong(f),
+      minmemtype42=readulong(f),
+      maxmemtype42=readulong(f),
+      minmemtype1=readulong(f),
+      maxmemtype1=readulong(f),
+    }
+    if not specification.glyphs then
+    elseif version==1.0 then
+      for index=0,#standardromanencoding do
+        glyphs[index].name=standardromanencoding[index]
+      end
+    elseif version==2.0 then
+      local glyphs=fontdata.glyphs
+      local nofglyphs=readushort(f)
+      local indices={}
+      local names={}
+      local maxnames=0
+      for i=0,nofglyphs-1 do
+        local nameindex=readushort(f)
+        if nameindex>=258 then
+          maxnames=maxnames+1
+          nameindex=nameindex-257
+          indices[nameindex]=i
+        else
+          glyphs[i].name=standardromanencoding[nameindex]
+        end
+      end
+      for i=1,maxnames do
+        local mapping=indices[i]
+        if not mapping then
+          report("quit post name fetching at %a of %a: %s",i,maxnames,"no index")
+          break
+        else
+          local length=readbyte(f)
+          if length>0 then
+            glyphs[mapping].name=readstring(f,length)
+          else
+            report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow")
+            break
+          end
+        end
+      end
+    elseif version==2.5 then
+    elseif version==3.0 then
+    end
+  else
+    fontdata.postscript={}
+  end
+end
+readers.cff=function(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"cff",specification.glyphs)
+end
+local formatreaders={}
+local duplicatestoo=true
+local sequence={
+  { 3,1,4 },
+  { 3,10,12 },
+  { 0,3,4 },
+  { 0,1,4 },
+  { 0,0,6 },
+  { 3,0,6 },
+  { 0,5,14 },
+{ 0,4,12 },
+  { 3,10,13 },
+}
+local supported={}
+for i=1,#sequence do
+  local si=sequence[i]
+  local sp,se,sf=si[1],si[2],si[3]
+  local p=supported[sp]
+  if not p then
+    p={}
+    supported[sp]=p
+  end
+  local e=p[se]
+  if not e then
+    e={}
+    p[se]=e
+  end
+  e[sf]=true
+end
+formatreaders[4]=function(f,fontdata,offset)
+  setposition(f,offset+2)
+  local length=readushort(f) 
+  local language=readushort(f)
+  local nofsegments=readushort(f)/2
+  skipshort(f,3)
+  local mapping=fontdata.mapping
+  local glyphs=fontdata.glyphs
+  local duplicates=fontdata.duplicates
+  local nofdone=0
+  local endchars=readcardinaltable(f,nofsegments,ushort)
+  local reserved=readushort(f) 
+  local startchars=readcardinaltable(f,nofsegments,ushort)
+  local deltas=readcardinaltable(f,nofsegments,ushort)
+  local offsets=readcardinaltable(f,nofsegments,ushort)
+  local size=(length-2*2-5*2-4*2*nofsegments)/2
+  local indices=readcardinaltable(f,size-1,ushort)
+  for segment=1,nofsegments do
+    local startchar=startchars[segment]
+    local endchar=endchars[segment]
+    local offset=offsets[segment]
+    local delta=deltas[segment]
+    if startchar==0xFFFF and endchar==0xFFFF then
+    elseif startchar==0xFFFF and offset==0 then
+    elseif offset==0xFFFF then
+    elseif offset==0 then
+      if trace_cmap_detail then
+        report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536)
+      end
+      for unicode=startchar,endchar do
+        local index=(unicode+delta)%65536
+        if index and index>0 then
+          local glyph=glyphs[index]
+          if glyph then
+            local gu=glyph.unicode
+            if not gu then
+              glyph.unicode=unicode
+              nofdone=nofdone+1
+            elseif gu~=unicode then
+              if duplicatestoo then
+                local d=duplicates[gu]
+                if d then
+                  d[unicode]=true
+                else
+                  duplicates[gu]={ [unicode]=true }
+                end
+              else
+                report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name)
+              end
+            end
+            if not mapping[index] then
+              mapping[index]=unicode
+            end
+          end
+        end
+      end
+    else
+      local shift=(segment-nofsegments+offset/2)-startchar
+      if trace_cmap_detail then
+        report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536)
+      end
+      for unicode=startchar,endchar do
+        local slot=shift+unicode
+        local index=indices[slot]
+        if index and index>0 then
+          index=(index+delta)%65536
+          local glyph=glyphs[index]
+          if glyph then
+            local gu=glyph.unicode
+            if not gu then
+              glyph.unicode=unicode
+              nofdone=nofdone+1
+            elseif gu~=unicode then
+              if duplicatestoo then
+                local d=duplicates[gu]
+                if d then
+                  d[unicode]=true
+                else
+                  duplicates[gu]={ [unicode]=true }
+                end
+              else
+                report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name)
+              end
+            end
+            if not mapping[index] then
+              mapping[index]=unicode
+            end
+          end
+        end
+      end
+    end
+  end
+  return nofdone
+end
+formatreaders[6]=function(f,fontdata,offset)
+  setposition(f,offset) 
+  local format=readushort(f)
+  local length=readushort(f)
+  local language=readushort(f)
+  local mapping=fontdata.mapping
+  local glyphs=fontdata.glyphs
+  local duplicates=fontdata.duplicates
+  local start=readushort(f)
+  local count=readushort(f)
+  local stop=start+count-1
+  local nofdone=0
+  if trace_cmap_detail then
+    report("format 6 from %C to %C",2,start,stop)
+  end
+  for unicode=start,stop do
+    local index=readushort(f)
+    if index>0 then
+      local glyph=glyphs[index]
+      if glyph then
+        local gu=glyph.unicode
+        if not gu then
+          glyph.unicode=unicode
+          nofdone=nofdone+1
+        elseif gu~=unicode then
+        end
+        if not mapping[index] then
+          mapping[index]=unicode
+        end
+      end
+    end
+  end
+  return nofdone
+end
+formatreaders[12]=function(f,fontdata,offset)
+  setposition(f,offset+2+2+4+4) 
+  local mapping=fontdata.mapping
+  local glyphs=fontdata.glyphs
+  local duplicates=fontdata.duplicates
+  local nofgroups=readulong(f)
+  local nofdone=0
+  for i=1,nofgroups do
+    local first=readulong(f)
+    local last=readulong(f)
+    local index=readulong(f)
+    if trace_cmap_detail then
+      report("format 12 from %C to %C starts at index %i",first,last,index)
+    end
+    for unicode=first,last do
+      local glyph=glyphs[index]
+      if glyph then
+        local gu=glyph.unicode
+        if not gu then
+          glyph.unicode=unicode
+          nofdone=nofdone+1
+        elseif gu~=unicode then
+          local d=duplicates[gu]
+          if d then
+            d[unicode]=true
+          else
+            duplicates[gu]={ [unicode]=true }
+          end
+        end
+        if not mapping[index] then
+          mapping[index]=unicode
+        end
+      end
+      index=index+1
+    end
+  end
+  return nofdone
+end
+formatreaders[13]=function(f,fontdata,offset)
+  setposition(f,offset+2+2+4+4) 
+  local mapping=fontdata.mapping
+  local glyphs=fontdata.glyphs
+  local duplicates=fontdata.duplicates
+  local nofgroups=readulong(f)
+  local nofdone=0
+  for i=1,nofgroups do
+    local first=readulong(f)
+    local last=readulong(f)
+    local index=readulong(f)
+    if first<privateoffset then
+      if trace_cmap_detail then
+        report("format 13 from %C to %C get index %i",first,last,index)
+      end
+      local glyph=glyphs[index]
+      local unicode=glyph.unicode
+      if not unicode then
+        unicode=first
+        glyph.unicode=unicode
+        first=first+1
+      end
+      local list=duplicates[unicode]
+      mapping[index]=unicode
+      if not list then
+        list={}
+        duplicates[unicode]=list
+      end
+      if last>=privateoffset then
+        local limit=privateoffset-1
+        report("format 13 from %C to %C pruned to %C",first,last,limit)
+        last=limit
+      end
+      for unicode=first,last do
+        list[unicode]=true
+      end
+      nofdone=nofdone+last-first+1
+    else
+      report("format 13 from %C to %C ignored",first,last)
+    end
+  end
+  return nofdone
+end
+formatreaders[14]=function(f,fontdata,offset)
+  if offset and offset~=0 then
+    setposition(f,offset)
+    local format=readushort(f)
+    local length=readulong(f)
+    local nofrecords=readulong(f)
+    local records={}
+    local variants={}
+    local nofdone=0
+    fontdata.variants=variants
+    for i=1,nofrecords do
+      records[i]={
+        selector=readuint(f),
+        default=readulong(f),
+        other=readulong(f),
+      }
+    end
+    for i=1,nofrecords do
+      local record=records[i]
+      local selector=record.selector
+      local default=record.default
+      local other=record.other
+      local other=record.other
+      if other~=0 then
+        setposition(f,offset+other)
+        local mapping={}
+        local count=readulong(f)
+        for i=1,count do
+          mapping[readuint(f)]=readushort(f)
+        end
+        nofdone=nofdone+count
+        variants[selector]=mapping
+      end
+    end
+    return nofdone
+  else
+    return 0
+  end
+end
+local function checkcmap(f,fontdata,records,platform,encoding,format)
+  local data=records[platform]
+  if not data then
+    return 0
+  end
+  data=data[encoding]
+  if not data then
+    return 0
+  end
+  data=data[format]
+  if not data then
+    return 0
+  end
+  local reader=formatreaders[format]
+  if not reader then
+    return 0
+  end
+  local p=platforms[platform]
+  local e=encodings[p]
+  local n=reader(f,fontdata,data) or 0
+  if trace_cmap then
+    report("cmap checked: platform %i (%s), encoding %i (%s), format %i, new unicodes %i",platform,p,encoding,e and e[encoding] or "?",format,n)
+  end
+  return n
+end
+function readers.cmap(f,fontdata,specification)
+  local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs)
+  if tableoffset then
+    local version=readushort(f)
+    local noftables=readushort(f)
+    local records={}
+    local unicodecid=false
+    local variantcid=false
+    local variants={}
+    local duplicates=fontdata.duplicates or {}
+    fontdata.duplicates=duplicates
+    for i=1,noftables do
+      local platform=readushort(f)
+      local encoding=readushort(f)
+      local offset=readulong(f)
+      local record=records[platform]
+      if not record then
+        records[platform]={
+          [encoding]={
+            offsets={ offset },
+            formats={},
+          }
+        }
+      else
+        local subtables=record[encoding]
+        if not subtables then
+          record[encoding]={
+            offsets={ offset },
+            formats={},
+          }
+        else
+          local offsets=subtables.offsets
+          offsets[#offsets+1]=offset
+        end
+      end
+    end
+    if trace_cmap then
+      report("found cmaps:")
+    end
+    for platform,record in sortedhash(records) do
+      local p=platforms[platform]
+      local e=encodings[p]
+      local sp=supported[platform]
+      local ps=p or "?"
+      if trace_cmap then
+        if sp then
+          report("  platform %i: %s",platform,ps)
+        else
+          report("  platform %i: %s (unsupported)",platform,ps)
+        end
+      end
+      for encoding,subtables in sortedhash(record) do
+        local se=sp and sp[encoding]
+        local es=e and e[encoding] or "?"
+        if trace_cmap then
+          if se then
+            report("    encoding %i: %s",encoding,es)
+          else
+            report("    encoding %i: %s (unsupported)",encoding,es)
+          end
+        end
+        local offsets=subtables.offsets
+        local formats=subtables.formats
+        for i=1,#offsets do
+          local offset=tableoffset+offsets[i]
+          setposition(f,offset)
+          formats[readushort(f)]=offset
+        end
+        record[encoding]=formats
+        if trace_cmap then
+          local list=sortedkeys(formats)
+          for i=1,#list do
+            if not (se and se[list[i]]) then
+              list[i]=list[i].." (unsupported)"
+            end
+          end
+          report("      formats: % t",list)
+        end
+      end
+    end
+    local ok=false
+    for i=1,#sequence do
+      local si=sequence[i]
+      local sp,se,sf=si[1],si[2],si[3]
+      if checkcmap(f,fontdata,records,sp,se,sf)>0 then
+        ok=true
+      end
+    end
+    if not ok then
+      report("no useable unicode cmap found")
+    end
+    fontdata.cidmaps={
+      version=version,
+      noftables=noftables,
+      records=records,
+    }
+  else
+    fontdata.cidmaps={}
+  end
+end
+function readers.loca(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"loca",specification.glyphs)
+end
+function readers.glyf(f,fontdata,specification) 
+  reportskippedtable(f,fontdata,"glyf",specification.glyphs)
+end
+function readers.colr(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"colr",specification.glyphs)
+end
+function readers.cpal(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"cpal",specification.glyphs)
+end
+function readers.svg(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"svg",specification.glyphs)
+end
+function readers.sbix(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"sbix",specification.glyphs)
+end
+function readers.cbdt(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"cbdt",specification.glyphs)
+end
+function readers.cblc(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"cblc",specification.glyphs)
+end
+function readers.ebdt(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"ebdt",specification.glyphs)
+end
+function readers.ebsc(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"ebsc",specification.glyphs)
+end
+function readers.eblc(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"eblc",specification.glyphs)
+end
+function readers.kern(f,fontdata,specification)
+  local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns)
+  if tableoffset then
+    local version=readushort(f)
+    local noftables=readushort(f)
+    for i=1,noftables do
+      local version=readushort(f)
+      local length=readushort(f)
+      local coverage=readushort(f)
+      local format=rshift(coverage,8) 
+      if format==0 then
+        local nofpairs=readushort(f)
+        local searchrange=readushort(f)
+        local entryselector=readushort(f)
+        local rangeshift=readushort(f)
+        local kerns={}
+        local glyphs=fontdata.glyphs
+        for i=1,nofpairs do
+          local left=readushort(f)
+          local right=readushort(f)
+          local kern=readfword(f)
+          local glyph=glyphs[left]
+          local kerns=glyph.kerns
+          if kerns then
+            kerns[right]=kern
+          else
+            glyph.kerns={ [right]=kern }
+          end
+        end
+      elseif format==2 then
+        report("todo: kern classes")
+      else
+        report("todo: kerns")
+      end
+    end
+  end
+end
+function readers.gdef(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"gdef",specification.details)
+end
+function readers.gsub(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"gsub",specification.details)
+end
+function readers.gpos(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"gpos",specification.details)
+end
+function readers.math(f,fontdata,specification)
+  reportskippedtable(f,fontdata,"math",specification.details)
+end
+local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames)
+  local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata
+  local names=fontdata.names
+  local info=nil
+  if names then
+    local metrics=fontdata.windowsmetrics or {}
+    local postscript=fontdata.postscript   or {}
+    local fontheader=fontdata.fontheader   or {}
+    local cffinfo=fontdata.cffinfo    or {}
+    local filename=fontdata.filename
+    local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight)
+    local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width )
+    local fontname=getname(fontdata,"postscriptname")
+    local fullname=getname(fontdata,"fullname")
+    local family=getname(fontdata,"family")
+    local subfamily=getname(fontdata,"subfamily")
+    local familyname=getname(fontdata,"typographicfamily")
+    local subfamilyname=getname(fontdata,"typographicsubfamily")
+    local compatiblename=getname(fontdata,"compatiblefullname") 
+    if rawfamilynames then
+    else
+      if not  familyname then  familyname=family end
+      if not subfamilyname then subfamilyname=subfamily end
+    end
+    if platformnames then
+      platformnames=fontdata.platformnames
+    end
+    if instancenames then
+      local variabledata=fontdata.variabledata
+      if variabledata then
+        local instances=variabledata and variabledata.instances
+        if instances then
+          instancenames={}
+          for i=1,#instances do
+            instancenames[i]=lower(stripstring(instances[i].subfamily))
+          end
+        else
+          instancenames=nil
+        end
+      else
+        instancenames=nil
+      end
+    end
+    info={ 
+      subfontindex=fontdata.subfontindex or sub or 0,
+      version=getname(fontdata,"version"),
+      fontname=fontname,
+      fullname=fullname,
+      family=family,
+      subfamily=subfamily,
+      familyname=familyname,
+      subfamilyname=subfamilyname,
+      compatiblename=compatiblename,
+      weight=weight and lower(weight),
+      width=width and lower(width),
+      pfmweight=metrics.weightclass or 400,
+      pfmwidth=metrics.widthclass or 5,
+      panosewidth=metrics.panosewidth,
+      panoseweight=metrics.panoseweight,
+      italicangle=postscript.italicangle or 0,
+      units=fontheader.units or 0,
+      designsize=fontdata.designsize,
+      minsize=fontdata.minsize,
+      maxsize=fontdata.maxsize,
+      monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced",
+      averagewidth=metrics.averagewidth,
+      xheight=metrics.xheight,
+      capheight=metrics.capheight,
+      ascender=metrics.typoascender,
+      descender=metrics.typodescender,
+      platformnames=platformnames or nil,
+      instancenames=instancenames or nil,
+    }
+    if metricstoo then
+      local keys={
+        "version",
+        "ascender","descender","linegap",
+        "maxadvancewidth","maxadvanceheight","maxextent",
+        "minbottomsidebearing","mintopsidebearing",
+      }
+      local h=fontdata.horizontalheader or {}
+      local v=fontdata.verticalheader  or {}
+      if h then
+        local th={}
+        local tv={}
+        for i=1,#keys do
+          local key=keys[i]
+          th[key]=h[key] or 0
+          tv[key]=v[key] or 0
+        end
+        info.horizontalmetrics=th
+        info.verticalmetrics=tv
+      end
+    end
+  elseif n then
+    info={
+      filename=fontdata.filename,
+      comment="there is no info for subfont "..n,
+    }
+  else
+    info={
+      filename=fontdata.filename,
+      comment="there is no info",
+    }
+  end
+  return info
+end
+local function loadtables(f,specification,offset)
+  if offset then
+    setposition(f,offset)
+  end
+  local tables={}
+  local basename=file.basename(specification.filename)
+  local filesize=specification.filesize
+  local filetime=specification.filetime
+  local fontdata={ 
+    filename=basename,
+    filesize=filesize,
+    filetime=filetime,
+    version=readstring(f,4),
+    noftables=readushort(f),
+    searchrange=readushort(f),
+    entryselector=readushort(f),
+    rangeshift=readushort(f),
+    tables=tables,
+    foundtables=false,
+  }
+  for i=1,fontdata.noftables do
+    local tag=lower(stripstring(readstring(f,4)))
+    local checksum=readulong(f) 
+    local offset=readulong(f)
+    local length=readulong(f)
+    if offset+length>filesize then
+      report("bad %a table in file %a",tag,basename)
+    end
+    tables[tag]={
+      checksum=checksum,
+      offset=offset,
+      length=length,
+    }
+  end
+  fontdata.foundtables=sortedkeys(tables)
+  if tables.cff or tables.cff2 then
+    fontdata.format="opentype"
+  else
+    fontdata.format="truetype"
+  end
+  return fontdata
+end
+local function prepareglyps(fontdata)
+  local glyphs=setmetatableindex(function(t,k)
+    local v={
+      index=k,
+    }
+    t[k]=v
+    return v
+  end)
+  fontdata.glyphs=glyphs
+  fontdata.mapping={}
+end
+local function readtable(tag,f,fontdata,specification,...)
+  local reader=readers[tag]
+  if reader then
+    reader(f,fontdata,specification,...)
+  end
+end
+local variablefonts_supported=(context and true) or (logs and logs.application and true) or false
+local function readdata(f,offset,specification)
+  local fontdata=loadtables(f,specification,offset)
+  if specification.glyphs then
+    prepareglyps(fontdata)
+  end
+  if not variablefonts_supported then
+    specification.instance=nil
+    specification.variable=nil
+    specification.factors=nil
+  end
+  fontdata.temporary={}
+  readtable("name",f,fontdata,specification)
+  local askedname=specification.askedname
+  if askedname then
+    local fullname=getname(fontdata,"fullname") or ""
+    local cleanname=gsub(askedname,"[^a-zA-Z0-9]","")
+    local foundname=gsub(fullname,"[^a-zA-Z0-9]","")
+    if lower(cleanname)~=lower(foundname) then
+      return 
+    end
+  end
+  readtable("stat",f,fontdata,specification)
+  readtable("avar",f,fontdata,specification)
+  readtable("fvar",f,fontdata,specification)
+  if variablefonts_supported then
+    local variabledata=fontdata.variabledata
+    if variabledata then
+      local instances=variabledata.instances
+      local axis=variabledata.axis
+      if axis and (not instances or #instances==0) then
+        instances={}
+        variabledata.instances=instances
+        local function add(n,subfamily,value)
+          local values={}
+          for i=1,#axis do
+            local a=axis[i]
+            values[i]={
+              axis=a.tag,
+              value=i==n and value or a.default,
+            }
+          end
+          instances[#instances+1]={
+            subfamily=subfamily,
+            values=values,
+          }
+        end
+        for i=1,#axis do
+          local a=axis[i]
+          local tag=a.tag
+          add(i,"default"..tag,a.default)
+          add(i,"minimum"..tag,a.minimum)
+          add(i,"maximum"..tag,a.maximum)
+        end
+      end
+    end
+    if not specification.factors then
+      local instance=specification.instance
+      if type(instance)=="string" then
+        local factors=helpers.getfactors(fontdata,instance)
+        if factors then
+          specification.factors=factors
+          fontdata.factors=factors
+          fontdata.instance=instance
+          report("user instance: %s, factors: % t",instance,factors)
+        else
+          report("user instance: %s, bad factors",instance)
+        end
+      end
+    end
+    if not fontdata.factors then
+      if fontdata.variabledata then
+        local factors=helpers.getfactors(fontdata,true)
+        if factors then
+          specification.factors=factors
+          fontdata.factors=factors
+        end
+      else
+      end
+    end
+  end
+  readtable("os/2",f,fontdata,specification)
+  readtable("head",f,fontdata,specification)
+  readtable("maxp",f,fontdata,specification)
+  readtable("hhea",f,fontdata,specification)
+  readtable("vhea",f,fontdata,specification)
+  readtable("hmtx",f,fontdata,specification)
+  readtable("vmtx",f,fontdata,specification)
+  readtable("vorg",f,fontdata,specification)
+  readtable("post",f,fontdata,specification)
+  readtable("mvar",f,fontdata,specification)
+  readtable("hvar",f,fontdata,specification)
+  readtable("vvar",f,fontdata,specification)
+  readtable("gdef",f,fontdata,specification)
+  readtable("cff",f,fontdata,specification)
+  readtable("cff2",f,fontdata,specification)
+  readtable("cmap",f,fontdata,specification)
+  readtable("loca",f,fontdata,specification) 
+  readtable("glyf",f,fontdata,specification) 
+  readtable("colr",f,fontdata,specification)
+  readtable("cpal",f,fontdata,specification)
+  readtable("svg",f,fontdata,specification)
+  readtable("sbix",f,fontdata,specification)
+  readtable("cbdt",f,fontdata,specification)
+  readtable("cblc",f,fontdata,specification)
+  readtable("ebdt",f,fontdata,specification)
+  readtable("eblc",f,fontdata,specification)
+  readtable("kern",f,fontdata,specification)
+  readtable("gsub",f,fontdata,specification)
+  readtable("gpos",f,fontdata,specification)
+  readtable("math",f,fontdata,specification)
+  fontdata.locations=nil
+  fontdata.tables=nil
+  fontdata.cidmaps=nil
+  fontdata.dictionaries=nil
+  return fontdata
+end
+local function loadfontdata(specification)
+  local filename=specification.filename
+  local fileattr=lfs.attributes(filename)
+  local filesize=fileattr and fileattr.size or 0
+  local filetime=fileattr and fileattr.modification or 0
+  local f=openfile(filename,true) 
+  if not f then
+    report("unable to open %a",filename)
+  elseif filesize==0 then
+    report("empty file %a",filename)
+    closefile(f)
+  else
+    specification.filesize=filesize
+    specification.filetime=filetime
+    local version=readstring(f,4)
+    local fontdata=nil
+    if version=="OTTO" or version=="true" or version=="\0\1\0\0" then
+      fontdata=readdata(f,0,specification)
+    elseif version=="ttcf" then
+      local subfont=tonumber(specification.subfont)
+      local ttcversion=readulong(f)
+      local nofsubfonts=readulong(f)
+      local offsets=readcardinaltable(f,nofsubfonts,ulong)
+      if subfont then 
+        if subfont>=1 and subfont<=nofsubfonts then
+          fontdata=readdata(f,offsets[subfont],specification)
+        else
+          report("no subfont %a in file %a",subfont,filename)
+        end
+      else
+        subfont=specification.subfont
+        if type(subfont)=="string" and subfont~="" then
+          specification.askedname=subfont
+          for i=1,nofsubfonts do
+            fontdata=readdata(f,offsets[i],specification)
+            if fontdata then
+              fontdata.subfontindex=i
+              report("subfont named %a has index %a",subfont,i)
+              break
+            end
+          end
+          if not fontdata then
+            report("no subfont named %a",subfont)
+          end
+        else
+          local subfonts={}
+          fontdata={
+            filename=filename,
+            filesize=filesize,
+            filetime=filetime,
+            version=version,
+            subfonts=subfonts,
+            ttcversion=ttcversion,
+            nofsubfonts=nofsubfonts,
+          }
+          for i=1,nofsubfonts do
+            subfonts[i]=readdata(f,offsets[i],specification)
+          end
+        end
+      end
+    else
+      report("unknown version %a in file %a",version,filename)
+    end
+    closefile(f)
+    return fontdata or {}
+  end
+end
+local function loadfont(specification,n,instance)
+  if type(specification)=="string" then
+    specification={
+      filename=specification,
+      info=true,
+      details=true,
+      glyphs=true,
+      shapes=true,
+      kerns=true,
+      variable=true,
+      globalkerns=true,
+      lookups=true,
+      subfont=n or true,
+      tounicode=false,
+      instance=instance
+    }
+  end
+  if specification.shapes or specification.lookups or specification.kerns then
+    specification.glyphs=true
+  end
+  if specification.glyphs then
+    specification.details=true
+  end
+  if specification.details then
+    specification.info=true 
+  end
+  if specification.platformnames then
+    specification.platformnames=true 
+  end
+  if specification.instance or instance then
+    specification.variable=true
+    specification.instance=specification.instance or instance
+  end
+  local function message(str)
+    report("fatal error in file %a: %s\n%s",specification.filename,str,debug.traceback())
+  end
+  local ok,result=xpcall(loadfontdata,message,specification)
+  if ok then
+    return result
+  end
+end
+function readers.loadshapes(filename,n,instance,streams)
+  local fontdata=loadfont {
+    filename=filename,
+    shapes=true,
+    streams=streams,
+    variable=true,
+    subfont=n,
+    instance=instance,
+  }
+  if fontdata then
+    for k,v in next,fontdata.glyphs do
+      v.class=nil
+      v.index=nil
+      v.math=nil
+    end
+  end
+  return fontdata and {
+    filename=filename,
+    format=fontdata.format,
+    glyphs=fontdata.glyphs,
+    units=fontdata.fontheader.units,
+  } or {
+    filename=filename,
+    format="unknown",
+    glyphs={},
+    units=0,
+  }
+end
+function readers.loadfont(filename,n,instance)
+  local fontdata=loadfont {
+    filename=filename,
+    glyphs=true,
+    shapes=false,
+    lookups=true,
+    variable=true,
+    subfont=n,
+    instance=instance,
+  }
+  if fontdata then
+    return {
+      tableversion=tableversion,
+      creator="context mkiv",
+      size=fontdata.filesize,
+      time=fontdata.filetime,
+      glyphs=fontdata.glyphs,
+      descriptions=fontdata.descriptions,
+      format=fontdata.format,
+      goodies={},
+      metadata=getinfo(fontdata,n,false,false,true,true),
+      properties={
+        hasitalics=fontdata.hasitalics or false,
+        maxcolorclass=fontdata.maxcolorclass,
+        hascolor=fontdata.hascolor or false,
+        instance=fontdata.instance,
+        factors=fontdata.factors,
+      },
+      resources={
+        filename=filename,
+        private=privateoffset,
+        duplicates=fontdata.duplicates or {},
+        features=fontdata.features  or {},
+        sublookups=fontdata.sublookups or {},
+        marks=fontdata.marks    or {},
+        markclasses=fontdata.markclasses or {},
+        marksets=fontdata.marksets  or {},
+        sequences=fontdata.sequences  or {},
+        variants=fontdata.variants,
+        version=getname(fontdata,"version"),
+        cidinfo=fontdata.cidinfo,
+        mathconstants=fontdata.mathconstants,
+        colorpalettes=fontdata.colorpalettes,
+        svgshapes=fontdata.svgshapes,
+        sbixshapes=fontdata.sbixshapes,
+        variabledata=fontdata.variabledata,
+        foundtables=fontdata.foundtables,
+      },
+    }
+  end
+end
+function readers.getinfo(filename,specification)
+  local subfont=nil
+  local platformnames=false
+  local rawfamilynames=false
+  local instancenames=true
+  if type(specification)=="table" then
+    subfont=tonumber(specification.subfont)
+    platformnames=specification.platformnames
+    rawfamilynames=specification.rawfamilynames
+  else
+    subfont=tonumber(specification)
+  end
+  local fontdata=loadfont {
+    filename=filename,
+    details=true,
+    platformnames=platformnames,
+    instancenames=true,
+  }
+  if fontdata then
+    local subfonts=fontdata.subfonts
+    if not subfonts then
+      return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames)
+    elseif not subfont then
+      local info={}
+      for i=1,#subfonts do
+        info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames)
+      end
+      return info
+    elseif subfont>=1 and subfont<=#subfonts then
+      return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames)
+    else
+      return {
+        filename=filename,
+        comment="there is no subfont "..subfont.." in this file"
+      }
+    end
+  else
+    return {
+      filename=filename,
+      comment="the file cannot be opened for reading",
+    }
+  end
+end
+function readers.rehash(fontdata,hashmethod)
+  report("the %a helper is not yet implemented","rehash")
+end
+function readers.checkhash(fontdata)
+  report("the %a helper is not yet implemented","checkhash")
+end
+function readers.pack(fontdata,hashmethod)
+  report("the %a helper is not yet implemented","pack")
+end
+function readers.unpack(fontdata)
+  report("the %a helper is not yet implemented","unpack")
+end
+function readers.expand(fontdata)
+  report("the %a helper is not yet implemented","unpack")
+end
+function readers.compact(fontdata)
+  report("the %a helper is not yet implemented","compact")
+end
+local extenders={}
+function readers.registerextender(extender)
+  extenders[#extenders+1]=extender
+end
+function readers.extend(fontdata)
+  for i=1,#extenders do
+    local extender=extenders[i]
+    local name=extender.name or "unknown"
+    local action=extender.action
+    if action then
+      action(fontdata)
+    end
+  end
+end
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “font-otr”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “font-oti” 309a75f9c14b77d87e94eba827dc4e71] ---
+
+if not modules then modules={} end modules ['font-oti']={
+  version=1.001,
+  comment="companion to font-ini.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+local lower=string.lower
+local fonts=fonts
+local constructors=fonts.constructors
+local otf=constructors.handlers.otf
+local otffeatures=constructors.features.otf
+local registerotffeature=otffeatures.register
+local otftables=otf.tables or {}
+otf.tables=otftables
+local allocate=utilities.storage.allocate
+registerotffeature {
+  name="features",
+  description="initialization of feature handler",
+  default=true,
+}
+local function setmode(tfmdata,value)
+  if value then
+    tfmdata.properties.mode=lower(value)
+  end
+end
+otf.modeinitializer=setmode
+local function setlanguage(tfmdata,value)
+  if value then
+    local cleanvalue=lower(value)
+    local languages=otftables and otftables.languages
+    local properties=tfmdata.properties
+    if not languages then
+      properties.language=cleanvalue
+    elseif languages[value] then
+      properties.language=cleanvalue
+    else
+      properties.language="dflt"
+    end
+  end
+end
+local function setscript(tfmdata,value)
+  if value then
+    local cleanvalue=lower(value)
+    local scripts=otftables and otftables.scripts
+    local properties=tfmdata.properties
+    if not scripts then
+      properties.script=cleanvalue
+    elseif scripts[value] then
+      properties.script=cleanvalue
+    else
+      properties.script="dflt"
+    end
+  end
+end
+registerotffeature {
+  name="mode",
+  description="mode",
+  initializers={
+    base=setmode,
+    node=setmode,
+    plug=setmode,
+  }
+}
+registerotffeature {
+  name="language",
+  description="language",
+  initializers={
+    base=setlanguage,
+    node=setlanguage,
+    plug=setlanguage,
+  }
+}
+registerotffeature {
+  name="script",
+  description="script",
+  initializers={
+    base=setscript,
+    node=setscript,
+    plug=setscript,
+  }
+}
+otftables.featuretypes=allocate {
+  gpos_single="position",
+  gpos_pair="position",
+  gpos_cursive="position",
+  gpos_mark2base="position",
+  gpos_mark2ligature="position",
+  gpos_mark2mark="position",
+  gpos_context="position",
+  gpos_contextchain="position",
+  gsub_single="substitution",
+  gsub_multiple="substitution",
+  gsub_alternate="substitution",
+  gsub_ligature="substitution",
+  gsub_context="substitution",
+  gsub_contextchain="substitution",
+  gsub_reversecontextchain="substitution",
+  gsub_reversesub="substitution",
+}
+function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts)
+  if featuretype=="position" then
+    local default=scripts.dflt
+    if default then
+      if autoscript=="position" or autoscript==true then
+        return default
+      else
+        report_otf("script feature %s not applied, enable default positioning")
+      end
+    else
+    end
+  elseif featuretype=="substitution" then
+    local default=scripts.dflt
+    if default then
+      if autoscript=="substitution" or autoscript==true then
+        return default
+      end
+    end
+  end
+end
+function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
+  if featuretype=="position" then
+    local default=languages.dflt
+    if default then
+      if autolanguage=="position" or autolanguage==true then
+        return default
+      else
+        report_otf("language feature %s not applied, enable default positioning")
+      end
+    else
+    end
+  elseif featuretype=="substitution" then
+    local default=languages.dflt
+    if default then
+      if autolanguage=="substitution" or autolanguage==true then
+        return default
+      end
+    end
+  end
+end
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “font-oti”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “font-ott” a4dd9bc516bdb7669ee61d5207f899c6] ---
+
+if not modules then modules={} end modules ["font-ott"]={
+  version=1.001,
+  comment="companion to font-ini.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files",
+}
+local type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset
+local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find
+local sequenced=table.sequenced
+local is_boolean=string.is_boolean
+local setmetatableindex=table.setmetatableindex
+local setmetatablenewindex=table.setmetatablenewindex
+local allocate=utilities.storage.allocate
+local fonts=fonts
+local otf=fonts.handlers.otf
+local otffeatures=otf.features
+local tables=otf.tables or {}
+otf.tables=tables
+local statistics=otf.statistics or {}
+otf.statistics=statistics
+local scripts=allocate {
+  ["arab"]="arabic",
+  ["armi"]="imperial aramaic",
+  ["armn"]="armenian",
+  ["avst"]="avestan",
+  ["bali"]="balinese",
+  ["bamu"]="bamum",
+  ["batk"]="batak",
+  ["beng"]="bengali",
+  ["bng2"]="bengali variant 2",
+  ["bopo"]="bopomofo",
+  ["brah"]="brahmi",
+  ["brai"]="braille",
+  ["bugi"]="buginese",
+  ["buhd"]="buhid",
+  ["byzm"]="byzantine music",
+  ["cakm"]="chakma",
+  ["cans"]="canadian syllabics",
+  ["cari"]="carian",
+  ["cham"]="cham",
+  ["cher"]="cherokee",
+  ["copt"]="coptic",
+  ["cprt"]="cypriot syllabary",
+  ["cyrl"]="cyrillic",
+  ["deva"]="devanagari",
+  ["dev2"]="devanagari variant 2",
+  ["dsrt"]="deseret",
+  ["egyp"]="egyptian heiroglyphs",
+  ["ethi"]="ethiopic",
+  ["geor"]="georgian",
+  ["glag"]="glagolitic",
+  ["goth"]="gothic",
+  ["grek"]="greek",
+  ["gujr"]="gujarati",
+  ["gjr2"]="gujarati variant 2",
+  ["guru"]="gurmukhi",
+  ["gur2"]="gurmukhi variant 2",
+  ["hang"]="hangul",
+  ["hani"]="cjk ideographic",
+  ["hano"]="hanunoo",
+  ["hebr"]="hebrew",
+  ["ital"]="old italic",
+  ["jamo"]="hangul jamo",
+  ["java"]="javanese",
+  ["kali"]="kayah li",
+  ["kana"]="hiragana and katakana",
+  ["khar"]="kharosthi",
+  ["khmr"]="khmer",
+  ["knda"]="kannada",
+  ["knd2"]="kannada variant 2",
+  ["kthi"]="kaithi",
+  ["lana"]="tai tham",
+  ["lao" ]="lao",
+  ["latn"]="latin",
+  ["lepc"]="lepcha",
+  ["limb"]="limbu",
+  ["linb"]="linear b",
+  ["lisu"]="lisu",
+  ["lyci"]="lycian",
+  ["lydi"]="lydian",
+  ["mand"]="mandaic and mandaean",
+  ["math"]="mathematical alphanumeric symbols",
+  ["merc"]="meroitic cursive",
+  ["mero"]="meroitic hieroglyphs",
+  ["mlym"]="malayalam",
+  ["mlm2"]="malayalam variant 2",
+  ["mong"]="mongolian",
+  ["mtei"]="meitei Mayek",
+  ["musc"]="musical symbols",
+  ["mym2"]="myanmar variant 2",
+  ["mymr"]="myanmar",
+  ["nko" ]='n"ko',
+  ["ogam"]="ogham",
+  ["olck"]="ol chiki",
+  ["orkh"]="old turkic and orkhon runic",
+  ["orya"]="oriya",
+  ["ory2"]="odia variant 2",
+  ["osma"]="osmanya",
+  ["phag"]="phags-pa",
+  ["phli"]="inscriptional pahlavi",
+  ["phnx"]="phoenician",
+  ["prti"]="inscriptional parthian",
+  ["rjng"]="rejang",
+  ["runr"]="runic",
+  ["samr"]="samaritan",
+  ["sarb"]="old south arabian",
+  ["saur"]="saurashtra",
+  ["shaw"]="shavian",
+  ["shrd"]="sharada",
+  ["sinh"]="sinhala",
+  ["sora"]="sora sompeng",
+  ["sund"]="sundanese",
+  ["sylo"]="syloti nagri",
+  ["syrc"]="syriac",
+  ["tagb"]="tagbanwa",
+  ["takr"]="takri",
+  ["tale"]="tai le",
+  ["talu"]="tai lu",
+  ["taml"]="tamil",
+  ["tavt"]="tai viet",
+  ["telu"]="telugu",
+  ["tel2"]="telugu variant 2",
+  ["tfng"]="tifinagh",
+  ["tglg"]="tagalog",
+  ["thaa"]="thaana",
+  ["thai"]="thai",
+  ["tibt"]="tibetan",
+  ["tml2"]="tamil variant 2",
+  ["ugar"]="ugaritic cuneiform",
+  ["vai" ]="vai",
+  ["xpeo"]="old persian cuneiform",
+  ["xsux"]="sumero-akkadian cuneiform",
+  ["yi" ]="yi",
+}
+local languages=allocate {
+  ["aba" ]="abaza",
+  ["abk" ]="abkhazian",
+  ["ach" ]="acholi",
+  ["acr" ]="achi",
+  ["ady" ]="adyghe",
+  ["afk" ]="afrikaans",
+  ["afr" ]="afar",
+  ["agw" ]="agaw",
+  ["aio" ]="aiton",
+  ["aka" ]="akan",
+  ["als" ]="alsatian",
+  ["alt" ]="altai",
+  ["amh" ]="amharic",
+  ["ang" ]="anglo-saxon",
+  ["apph"]="phonetic transcription—americanist conventions",
+  ["ara" ]="arabic",
+  ["arg" ]="aragonese",
+  ["ari" ]="aari",
+  ["ark" ]="rakhine",
+  ["asm" ]="assamese",
+  ["ast" ]="asturian",
+  ["ath" ]="athapaskan",
+  ["avr" ]="avar",
+  ["awa" ]="awadhi",
+  ["aym" ]="aymara",
+  ["azb" ]="torki",
+  ["aze" ]="azerbaijani",
+  ["bad" ]="badaga",
+  ["bad0"]="banda",
+  ["bag" ]="baghelkhandi",
+  ["bal" ]="balkar",
+  ["ban" ]="balinese",
+  ["bar" ]="bavarian",
+  ["bau" ]="baulé",
+  ["bbc" ]="batak toba",
+  ["bbr" ]="berber",
+  ["bch" ]="bench",
+  ["bcr" ]="bible cree",
+  ["bdy" ]="bandjalang",
+  ["bel" ]="belarussian",
+  ["bem" ]="bemba",
+  ["ben" ]="bengali",
+  ["bgc" ]="haryanvi",
+  ["bgq" ]="bagri",
+  ["bgr" ]="bulgarian",
+  ["bhi" ]="bhili",
+  ["bho" ]="bhojpuri",
+  ["bik" ]="bikol",
+  ["bil" ]="bilen",
+  ["bis" ]="bislama",
+  ["bjj" ]="kanauji",
+  ["bkf" ]="blackfoot",
+  ["bli" ]="baluchi",
+  ["blk" ]="pa'o karen",
+  ["bln" ]="balante",
+  ["blt" ]="balti",
+  ["bmb" ]="bambara (bamanankan)",
+  ["bml" ]="bamileke",
+  ["bos" ]="bosnian",
+  ["bpy" ]="bishnupriya manipuri",
+  ["bre" ]="breton",
+  ["brh" ]="brahui",
+  ["bri" ]="braj bhasha",
+  ["brm" ]="burmese",
+  ["brx" ]="bodo",
+  ["bsh" ]="bashkir",
+  ["bti" ]="beti",
+  ["bts" ]="batak simalungun",
+  ["bug" ]="bugis",
+  ["cak" ]="kaqchikel",
+  ["cat" ]="catalan",
+  ["cbk" ]="zamboanga chavacano",
+  ["ceb" ]="cebuano",
+  ["cgg" ]="chiga",
+  ["cha" ]="chamorro",
+  ["che" ]="chechen",
+  ["chg" ]="chaha gurage",
+  ["chh" ]="chattisgarhi",
+  ["chi" ]="chichewa (chewa, nyanja)",
+  ["chk" ]="chukchi",
+  ["chk0"]="chuukese",
+  ["cho" ]="choctaw",
+  ["chp" ]="chipewyan",
+  ["chr" ]="cherokee",
+  ["chu" ]="chuvash",
+  ["chy" ]="cheyenne",
+  ["cmr" ]="comorian",
+  ["cop" ]="coptic",
+  ["cor" ]="cornish",
+  ["cos" ]="corsican",
+  ["cpp" ]="creoles",
+  ["cre" ]="cree",
+  ["crr" ]="carrier",
+  ["crt" ]="crimean tatar",
+  ["csb" ]="kashubian",
+  ["csl" ]="church slavonic",
+  ["csy" ]="czech",
+  ["ctg" ]="chittagonian",
+  ["cuk" ]="san blas kuna",
+  ["dan" ]="danish",
+  ["dar" ]="dargwa",
+  ["dax" ]="dayi",
+  ["dcr" ]="woods cree",
+  ["deu" ]="german",
+  ["dgo" ]="dogri",
+  ["dgr" ]="dogri",
+  ["dhg" ]="dhangu",
+  ["dhv" ]="divehi (dhivehi, maldivian)",
+  ["diq" ]="dimli",
+  ["div" ]="divehi (dhivehi, maldivian)",
+  ["djr" ]="zarma",
+  ["djr0"]="djambarrpuyngu",
+  ["dng" ]="dangme",
+  ["dnj" ]="dan",
+  ["dnk" ]="dinka",
+  ["dri" ]="dari",
+  ["duj" ]="dhuwal",
+  ["dun" ]="dungan",
+  ["dzn" ]="dzongkha",
+  ["ebi" ]="ebira",
+  ["ecr" ]="eastern cree",
+  ["edo" ]="edo",
+  ["efi" ]="efik",
+  ["ell" ]="greek",
+  ["emk" ]="eastern maninkakan",
+  ["eng" ]="english",
+  ["erz" ]="erzya",
+  ["esp" ]="spanish",
+  ["esu" ]="central yupik",
+  ["eti" ]="estonian",
+  ["euq" ]="basque",
+  ["evk" ]="evenki",
+  ["evn" ]="even",
+  ["ewe" ]="ewe",
+  ["fan" ]="french antillean",
+  ["fan0"]=" fang",
+  ["far" ]="persian",
+  ["fat" ]="fanti",
+  ["fin" ]="finnish",
+  ["fji" ]="fijian",
+  ["fle" ]="dutch (flemish)",
+  ["fne" ]="forest nenets",
+  ["fon" ]="fon",
+  ["fos" ]="faroese",
+  ["fra" ]="french",
+  ["frc" ]="cajun french",
+  ["fri" ]="frisian",
+  ["frl" ]="friulian",
+  ["frp" ]="arpitan",
+  ["fta" ]="futa",
+  ["ful" ]="fulah",
+  ["fuv" ]="nigerian fulfulde",
+  ["gad" ]="ga",
+  ["gae" ]="scottish gaelic (gaelic)",
+  ["gag" ]="gagauz",
+  ["gal" ]="galician",
+  ["gar" ]="garshuni",
+  ["gaw" ]="garhwali",
+  ["gez" ]="ge'ez",
+  ["gih" ]="githabul",
+  ["gil" ]="gilyak",
+  ["gil0"]="kiribati (gilbertese)",
+  ["gkp" ]="kpelle (guinea)",
+  ["glk" ]="gilaki",
+  ["gmz" ]="gumuz",
+  ["gnn" ]="gumatj",
+  ["gog" ]="gogo",
+  ["gon" ]="gondi",
+  ["grn" ]="greenlandic",
+  ["gro" ]="garo",
+  ["gua" ]="guarani",
+  ["guc" ]="wayuu",
+  ["guf" ]="gupapuyngu",
+  ["guj" ]="gujarati",
+  ["guz" ]="gusii",
+  ["hai" ]="haitian (haitian creole)",
+  ["hal" ]="halam",
+  ["har" ]="harauti",
+  ["hau" ]="hausa",
+  ["haw" ]="hawaiian",
+  ["hay" ]="haya",
+  ["haz" ]="hazaragi",
+  ["hbn" ]="hammer-banna",
+  ["her" ]="herero",
+  ["hil" ]="hiligaynon",
+  ["hin" ]="hindi",
+  ["hma" ]="high mari",
+  ["hmn" ]="hmong",
+  ["hmo" ]="hiri motu",
+  ["hnd" ]="hindko",
+  ["ho" ]="ho",
+  ["hri" ]="harari",
+  ["hrv" ]="croatian",
+  ["hun" ]="hungarian",
+  ["hye" ]="armenian",
+  ["hye0"]="armenian east",
+  ["iba" ]="iban",
+  ["ibb" ]="ibibio",
+  ["ibo" ]="igbo",
+  ["ido" ]="ido",
+  ["ijo" ]="ijo languages",
+  ["ile" ]="interlingue",
+  ["ilo" ]="ilokano",
+  ["ina" ]="interlingua",
+  ["ind" ]="indonesian",
+  ["ing" ]="ingush",
+  ["inu" ]="inuktitut",
+  ["ipk" ]="inupiat",
+  ["ipph"]="phonetic transcription—ipa conventions",
+  ["iri" ]="irish",
+  ["irt" ]="irish traditional",
+  ["isl" ]="icelandic",
+  ["ism" ]="inari sami",
+  ["ita" ]="italian",
+  ["iwr" ]="hebrew",
+  ["jam" ]="jamaican creole",
+  ["jan" ]="japanese",
+  ["jav" ]="javanese",
+  ["jbo" ]="lojban",
+  ["jii" ]="yiddish",
+  ["jud" ]="ladino",
+  ["jul" ]="jula",
+  ["kab" ]="kabardian",
+  ["kab0"]="kabyle",
+  ["kac" ]="kachchi",
+  ["kal" ]="kalenjin",
+  ["kan" ]="kannada",
+  ["kar" ]="karachay",
+  ["kat" ]="georgian",
+  ["kaz" ]="kazakh",
+  ["kde" ]="makonde",
+  ["kea" ]="kabuverdianu (crioulo)",
+  ["keb" ]="kebena",
+  ["kek" ]="kekchi",
+  ["kge" ]="khutsuri georgian",
+  ["kha" ]="khakass",
+  ["khk" ]="khanty-kazim",
+  ["khm" ]="khmer",
+  ["khs" ]="khanty-shurishkar",
+  ["kht" ]="khamti shan",
+  ["khv" ]="khanty-vakhi",
+  ["khw" ]="khowar",
+  ["kik" ]="kikuyu (gikuyu)",
+  ["kir" ]="kirghiz (kyrgyz)",
+  ["kis" ]="kisii",
+  ["kiu" ]="kirmanjki",
+  ["kjd" ]="southern kiwai",
+  ["kjp" ]="eastern pwo karen",
+  ["kkn" ]="kokni",
+  ["klm" ]="kalmyk",
+  ["kmb" ]="kamba",
+  ["kmn" ]="kumaoni",
+  ["kmo" ]="komo",
+  ["kms" ]="komso",
+  ["knr" ]="kanuri",
+  ["kod" ]="kodagu",
+  ["koh" ]="korean old hangul",
+  ["kok" ]="konkani",
+  ["kom" ]="komi",
+  ["kon" ]="kikongo",
+  ["kon0"]="kongo",
+  ["kop" ]="komi-permyak",
+  ["kor" ]="korean",
+  ["kos" ]="kosraean",
+  ["koz" ]="komi-zyrian",
+  ["kpl" ]="kpelle",
+  ["kri" ]="krio",
+  ["krk" ]="karakalpak",
+  ["krl" ]="karelian",
+  ["krm" ]="karaim",
+  ["krn" ]="karen",
+  ["krt" ]="koorete",
+  ["ksh" ]="kashmiri",
+  ["ksh0"]="ripuarian",
+  ["ksi" ]="khasi",
+  ["ksm" ]="kildin sami",
+  ["ksw" ]="s’gaw karen",
+  ["kua" ]="kuanyama",
+  ["kui" ]="kui",
+  ["kul" ]="kulvi",
+  ["kum" ]="kumyk",
+  ["kur" ]="kurdish",
+  ["kuu" ]="kurukh",
+  ["kuy" ]="kuy",
+  ["kyk" ]="koryak",
+  ["kyu" ]="western kayah",
+  ["lad" ]="ladin",
+  ["lah" ]="lahuli",
+  ["lak" ]="lak",
+  ["lam" ]="lambani",
+  ["lao" ]="lao",
+  ["lat" ]="latin",
+  ["laz" ]="laz",
+  ["lcr" ]="l-cree",
+  ["ldk" ]="ladakhi",
+  ["lez" ]="lezgi",
+  ["lij" ]="ligurian",
+  ["lim" ]="limburgish",
+  ["lin" ]="lingala",
+  ["lis" ]="lisu",
+  ["ljp" ]="lampung",
+  ["lki" ]="laki",
+  ["lma" ]="low mari",
+  ["lmb" ]="limbu",
+  ["lmo" ]="lombard",
+  ["lmw" ]="lomwe",
+  ["lom" ]="loma",
+  ["lrc" ]="luri",
+  ["lsb" ]="lower sorbian",
+  ["lsm" ]="lule sami",
+  ["lth" ]="lithuanian",
+  ["ltz" ]="luxembourgish",
+  ["lua" ]="luba-lulua",
+  ["lub" ]="luba-katanga",
+  ["lug" ]="ganda",
+  ["luh" ]="luyia",
+  ["luo" ]="luo",
+  ["lvi" ]="latvian",
+  ["mad" ]="madura",
+  ["mag" ]="magahi",
+  ["mah" ]="marshallese",
+  ["maj" ]="majang",
+  ["mak" ]="makhuwa",
+  ["mal" ]="malayalam reformed",
+  ["mam" ]="mam",
+  ["man" ]="mansi",
+  ["map" ]="mapudungun",
+  ["mar" ]="marathi",
+  ["maw" ]="marwari",
+  ["mbn" ]="mbundu",
+  ["mch" ]="manchu",
+  ["mcr" ]="moose cree",
+  ["mde" ]="mende",
+  ["mdr" ]="mandar",
+  ["men" ]="me'en",
+  ["mer" ]="meru",
+  ["mfe" ]="morisyen",
+  ["min" ]="minangkabau",
+  ["miz" ]="mizo",
+  ["mkd" ]="macedonian",
+  ["mkr" ]="makasar",
+  ["mkw" ]="kituba",
+  ["mle" ]="male",
+  ["mlg" ]="malagasy",
+  ["mln" ]="malinke",
+  ["mly" ]="malay",
+  ["mnd" ]="mandinka",
+  ["mng" ]="mongolian",
+  ["mni" ]="manipuri",
+  ["mnk" ]="maninka",
+  ["mnx" ]="manx",
+  ["moh" ]="mohawk",
+  ["mok" ]="moksha",
+  ["mol" ]="moldavian",
+  ["mon" ]="mon",
+  ["mor" ]="moroccan",
+  ["mos" ]="mossi",
+  ["mri" ]="maori",
+  ["mth" ]="maithili",
+  ["mts" ]="maltese",
+  ["mun" ]="mundari",
+  ["mus" ]="muscogee",
+  ["mwl" ]="mirandese",
+  ["mww" ]="hmong daw",
+  ["myn" ]="mayan",
+  ["mzn" ]="mazanderani",
+  ["nag" ]="naga-assamese",
+  ["nah" ]="nahuatl",
+  ["nan" ]="nanai",
+  ["nap" ]="neapolitan",
+  ["nas" ]="naskapi",
+  ["nau" ]="nauruan",
+  ["nav" ]="navajo",
+  ["ncr" ]="n-cree",
+  ["ndb" ]="ndebele",
+  ["ndc" ]="ndau",
+  ["ndg" ]="ndonga",
+  ["nds" ]="low saxon",
+  ["nep" ]="nepali",
+  ["new" ]="newari",
+  ["nga" ]="ngbaka",
+  ["ngr" ]="nagari",
+  ["nhc" ]="norway house cree",
+  ["nis" ]="nisi",
+  ["niu" ]="niuean",
+  ["nkl" ]="nyankole",
+  ["nko" ]="n'ko",
+  ["nld" ]="dutch",
+  ["noe" ]="nimadi",
+  ["nog" ]="nogai",
+  ["nor" ]="norwegian",
+  ["nov" ]="novial",
+  ["nsm" ]="northern sami",
+  ["nso" ]="sotho, northern",
+  ["nta" ]="northern tai",
+  ["nto" ]="esperanto",
+  ["nym" ]="nyamwezi",
+  ["nyn" ]="norwegian nynorsk",
+  ["oci" ]="occitan",
+  ["ocr" ]="oji-cree",
+  ["ojb" ]="ojibway",
+  ["ori" ]="odia",
+  ["oro" ]="oromo",
+  ["oss" ]="ossetian",
+  ["paa" ]="palestinian aramaic",
+  ["pag" ]="pangasinan",
+  ["pal" ]="pali",
+  ["pam" ]="pampangan",
+  ["pan" ]="punjabi",
+  ["pap" ]="palpa",
+  ["pap0"]="papiamentu",
+  ["pas" ]="pashto",
+  ["pau" ]="palauan",
+  ["pcc" ]="bouyei",
+  ["pcd" ]="picard",
+  ["pdc" ]="pennsylvania german",
+  ["pgr" ]="polytonic greek",
+  ["phk" ]="phake",
+  ["pih" ]="norfolk",
+  ["pil" ]="filipino",
+  ["plg" ]="palaung",
+  ["plk" ]="polish",
+  ["pms" ]="piemontese",
+  ["pnb" ]="western panjabi",
+  ["poh" ]="pocomchi",
+  ["pon" ]="pohnpeian",
+  ["pro" ]="provencal",
+  ["ptg" ]="portuguese",
+  ["pwo" ]="western pwo karen",
+  ["qin" ]="chin",
+  ["quc" ]="k’iche’",
+  ["quh" ]="quechua (bolivia)",
+  ["quz" ]="quechua",
+  ["qvi" ]="quechua (ecuador)",
+  ["qwh" ]="quechua (peru)",
+  ["raj" ]="rajasthani",
+  ["rar" ]="rarotongan",
+  ["rbu" ]="russian buriat",
+  ["rcr" ]="r-cree",
+  ["rej" ]="rejang",
+  ["ria" ]="riang",
+  ["rif" ]="tarifit",
+  ["rit" ]="ritarungo",
+  ["rkw" ]="arakwal",
+  ["rms" ]="romansh",
+  ["rmy" ]="vlax romani",
+  ["rom" ]="romanian",
+  ["roy" ]="romany",
+  ["rsy" ]="rusyn",
+  ["rtm" ]="rotuman",
+  ["rua" ]="kinyarwanda",
+  ["run" ]="rundi",
+  ["rup" ]="aromanian",
+  ["rus" ]="russian",
+  ["sad" ]="sadri",
+  ["san" ]="sanskrit",
+  ["sas" ]="sasak",
+  ["sat" ]="santali",
+  ["say" ]="sayisi",
+  ["scn" ]="sicilian",
+  ["sco" ]="scots",
+  ["sek" ]="sekota",
+  ["sel" ]="selkup",
+  ["sga" ]="old irish",
+  ["sgo" ]="sango",
+  ["sgs" ]="samogitian",
+  ["shi" ]="tachelhit",
+  ["shn" ]="shan",
+  ["sib" ]="sibe",
+  ["sid" ]="sidamo",
+  ["sig" ]="silte gurage",
+  ["sks" ]="skolt sami",
+  ["sky" ]="slovak",
+  ["sla" ]="slavey",
+  ["slv" ]="slovenian",
+  ["sml" ]="somali",
+  ["smo" ]="samoan",
+  ["sna" ]="sena",
+  ["sna0"]="shona",
+  ["snd" ]="sindhi",
+  ["snh" ]="sinhala (sinhalese)",
+  ["snk" ]="soninke",
+  ["sog" ]="sodo gurage",
+  ["sop" ]="songe",
+  ["sot" ]="sotho, southern",
+  ["sqi" ]="albanian",
+  ["srb" ]="serbian",
+  ["srd" ]="sardinian",
+  ["srk" ]="saraiki",
+  ["srr" ]="serer",
+  ["ssl" ]="south slavey",
+  ["ssm" ]="southern sami",
+  ["stq" ]="saterland frisian",
+  ["suk" ]="sukuma",
+  ["sun" ]="sundanese",
+  ["sur" ]="suri",
+  ["sva" ]="svan",
+  ["sve" ]="swedish",
+  ["swa" ]="swadaya aramaic",
+  ["swk" ]="swahili",
+  ["swz" ]="swati",
+  ["sxt" ]="sutu",
+  ["sxu" ]="upper saxon",
+  ["syl" ]="sylheti",
+  ["syr" ]="syriac",
+  ["szl" ]="silesian",
+  ["tab" ]="tabasaran",
+  ["taj" ]="tajiki",
+  ["tam" ]="tamil",
+  ["tat" ]="tatar",
+  ["tcr" ]="th-cree",
+  ["tdd" ]="dehong dai",
+  ["tel" ]="telugu",
+  ["tet" ]="tetum",
+  ["tgl" ]="tagalog",
+  ["tgn" ]="tongan",
+  ["tgr" ]="tigre",
+  ["tgy" ]="tigrinya",
+  ["tha" ]="thai",
+  ["tht" ]="tahitian",
+  ["tib" ]="tibetan",
+  ["tiv" ]="tiv",
+  ["tkm" ]="turkmen",
+  ["tmh" ]="tamashek",
+  ["tmn" ]="temne",
+  ["tna" ]="tswana",
+  ["tne" ]="tundra nenets",
+  ["tng" ]="tonga",
+  ["tod" ]="todo",
+  ["tod0"]="toma",
+  ["tpi" ]="tok pisin",
+  ["trk" ]="turkish",
+  ["tsg" ]="tsonga",
+  ["tua" ]="turoyo aramaic",
+  ["tul" ]="tulu",
+  ["tuv" ]="tuvin",
+  ["tvl" ]="tuvalu",
+  ["twi" ]="twi",
+  ["tyz" ]="tày",
+  ["tzm" ]="tamazight",
+  ["tzo" ]="tzotzil",
+  ["udm" ]="udmurt",
+  ["ukr" ]="ukrainian",
+  ["umb" ]="umbundu",
+  ["urd" ]="urdu",
+  ["usb" ]="upper sorbian",
+  ["uyg" ]="uyghur",
+  ["uzb" ]="uzbek",
+  ["vec" ]="venetian",
+  ["ven" ]="venda",
+  ["vit" ]="vietnamese",
+  ["vol" ]="volapük",
+  ["vro" ]="võro",
+  ["wa" ]="wa",
+  ["wag" ]="wagdi",
+  ["war" ]="waray-waray",
+  ["wcr" ]="west-cree",
+  ["wel" ]="welsh",
+  ["wlf" ]="wolof",
+  ["wln" ]="walloon",
+  ["xbd" ]="lü",
+  ["xhs" ]="xhosa",
+  ["xjb" ]="minjangbal",
+  ["xog" ]="soga",
+  ["xpe" ]="kpelle (liberia)",
+  ["yak" ]="sakha",
+  ["yao" ]="yao",
+  ["yap" ]="yapese",
+  ["yba" ]="yoruba",
+  ["ycr" ]="y-cree",
+  ["yic" ]="yi classic",
+  ["yim" ]="yi modern",
+  ["zea" ]="zealandic",
+  ["zgh" ]="standard morrocan tamazigh",
+  ["zha" ]="zhuang",
+  ["zhh" ]="chinese, hong kong sar",
+  ["zhp" ]="chinese phonetic",
+  ["zhs" ]="chinese simplified",
+  ["zht" ]="chinese traditional",
+  ["znd" ]="zande",
+  ["zul" ]="zulu",
+  ["zza" ]="zazaki",
+}
+local features=allocate {
+  ["aalt"]="access all alternates",
+  ["abvf"]="above-base forms",
+  ["abvm"]="above-base mark positioning",
+  ["abvs"]="above-base substitutions",
+  ["afrc"]="alternative fractions",
+  ["akhn"]="akhands",
+  ["blwf"]="below-base forms",
+  ["blwm"]="below-base mark positioning",
+  ["blws"]="below-base substitutions",
+  ["c2pc"]="petite capitals from capitals",
+  ["c2sc"]="small capitals from capitals",
+  ["calt"]="contextual alternates",
+  ["case"]="case-sensitive forms",
+  ["ccmp"]="glyph composition/decomposition",
+  ["cfar"]="conjunct form after ro",
+  ["cjct"]="conjunct forms",
+  ["clig"]="contextual ligatures",
+  ["cpct"]="centered cjk punctuation",
+  ["cpsp"]="capital spacing",
+  ["cswh"]="contextual swash",
+  ["curs"]="cursive positioning",
+  ["dflt"]="default processing",
+  ["dist"]="distances",
+  ["dlig"]="discretionary ligatures",
+  ["dnom"]="denominators",
+  ["dtls"]="dotless forms",
+  ["expt"]="expert forms",
+  ["falt"]="final glyph alternates",
+  ["fin2"]="terminal forms #2",
+  ["fin3"]="terminal forms #3",
+  ["fina"]="terminal forms",
+  ["flac"]="flattened accents over capitals",
+  ["frac"]="fractions",
+  ["fwid"]="full width",
+  ["half"]="half forms",
+  ["haln"]="halant forms",
+  ["halt"]="alternate half width",
+  ["hist"]="historical forms",
+  ["hkna"]="horizontal kana alternates",
+  ["hlig"]="historical ligatures",
+  ["hngl"]="hangul",
+  ["hojo"]="hojo kanji forms",
+  ["hwid"]="half width",
+  ["init"]="initial forms",
+  ["isol"]="isolated forms",
+  ["ital"]="italics",
+  ["jalt"]="justification alternatives",
+  ["jp04"]="jis2004 forms",
+  ["jp78"]="jis78 forms",
+  ["jp83"]="jis83 forms",
+  ["jp90"]="jis90 forms",
+  ["kern"]="kerning",
+  ["lfbd"]="left bounds",
+  ["liga"]="standard ligatures",
+  ["ljmo"]="leading jamo forms",
+  ["lnum"]="lining figures",
+  ["locl"]="localized forms",
+  ["ltra"]="left-to-right alternates",
+  ["ltrm"]="left-to-right mirrored forms",
+  ["mark"]="mark positioning",
+  ["med2"]="medial forms #2",
+  ["medi"]="medial forms",
+  ["mgrk"]="mathematical greek",
+  ["mkmk"]="mark to mark positioning",
+  ["mset"]="mark positioning via substitution",
+  ["nalt"]="alternate annotation forms",
+  ["nlck"]="nlc kanji forms",
+  ["nukt"]="nukta forms",
+  ["numr"]="numerators",
+  ["onum"]="old style figures",
+  ["opbd"]="optical bounds",
+  ["ordn"]="ordinals",
+  ["ornm"]="ornaments",
+  ["palt"]="proportional alternate width",
+  ["pcap"]="petite capitals",
+  ["pkna"]="proportional kana",
+  ["pnum"]="proportional figures",
+  ["pref"]="pre-base forms",
+  ["pres"]="pre-base substitutions",
+  ["pstf"]="post-base forms",
+  ["psts"]="post-base substitutions",
+  ["pwid"]="proportional widths",
+  ["qwid"]="quarter widths",
+  ["rand"]="randomize",
+  ["rclt"]="required contextual alternates",
+  ["rkrf"]="rakar forms",
+  ["rlig"]="required ligatures",
+  ["rphf"]="reph form",
+  ["rtbd"]="right bounds",
+  ["rtla"]="right-to-left alternates",
+  ["rtlm"]="right to left mirrored forms",
+  ["rvrn"]="required variation alternates",
+  ["ruby"]="ruby notation forms",
+  ["salt"]="stylistic alternates",
+  ["sinf"]="scientific inferiors",
+  ["size"]="optical size",
+  ["smcp"]="small capitals",
+  ["smpl"]="simplified forms",
+  ["ssty"]="script style",
+  ["stch"]="stretching glyph decomposition",
+  ["subs"]="subscript",
+  ["sups"]="superscript",
+  ["swsh"]="swash",
+  ["titl"]="titling",
+  ["tjmo"]="trailing jamo forms",
+  ["tnam"]="traditional name forms",
+  ["tnum"]="tabular figures",
+  ["trad"]="traditional forms",
+  ["twid"]="third widths",
+  ["unic"]="unicase",
+  ["valt"]="alternate vertical metrics",
+  ["vatu"]="vattu variants",
+  ["vert"]="vertical writing",
+  ["vhal"]="alternate vertical half metrics",
+  ["vjmo"]="vowel jamo forms",
+  ["vkna"]="vertical kana alternates",
+  ["vkrn"]="vertical kerning",
+  ["vpal"]="proportional alternate vertical metrics",
+  ["vrt2"]="vertical rotation",
+  ["zero"]="slashed zero",
+  ["trep"]="traditional tex replacements",
+  ["tlig"]="traditional tex ligatures",
+  ["ss.."]="stylistic set ..",
+  ["cv.."]="character variant ..",
+  ["js.."]="justification ..",
+  ["dv.."]="devanagari ..",
+  ["ml.."]="malayalam ..",
+}
+local baselines=allocate {
+  ["hang"]="hanging baseline",
+  ["icfb"]="ideographic character face bottom edge baseline",
+  ["icft"]="ideographic character face tope edige baseline",
+  ["ideo"]="ideographic em-box bottom edge baseline",
+  ["idtp"]="ideographic em-box top edge baseline",
+  ["math"]="mathematical centered baseline",
+  ["romn"]="roman baseline"
+}
+tables.scripts=scripts
+tables.languages=languages
+tables.features=features
+tables.baselines=baselines
+local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end)
+local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end)
+local report_checks=logs.reporter("fonts","checks")
+if otffeatures.features then
+  for k,v in next,otffeatures.features do
+    features[k]=v
+  end
+  otffeatures.features=features
+end
+local function swapped(h)
+  local r={}
+  for k,v in next,h do
+    r[gsub(v,"[^a-z0-9]","")]=k 
+  end
+  return r
+end
+local verbosescripts=allocate(swapped(scripts ))
+local verboselanguages=allocate(swapped(languages))
+local verbosefeatures=allocate(swapped(features ))
+local verbosebaselines=allocate(swapped(baselines))
+local function resolve(t,k)
+  if k then
+    k=gsub(lower(k),"[^a-z0-9]","")
+    local v=rawget(t,k)
+    if v then
+      return v
+    end
+  end
+end
+setmetatableindex(verbosescripts,resolve)
+setmetatableindex(verboselanguages,resolve)
+setmetatableindex(verbosefeatures,resolve)
+setmetatableindex(verbosebaselines,resolve)
+setmetatableindex(scripts,function(t,k)
+  if k then
+    k=lower(k)
+    if k=="dflt" then
+      return k
+    end
+    local v=rawget(t,k)
+    if v then
+      return v
+    end
+    k=gsub(k," ","")
+    v=rawget(t,v)
+    if v then
+      return v
+    elseif acceptscripts then
+      report_checks("registering extra script %a",k)
+      rawset(t,k,k)
+      return k
+    end
+  end
+  return "dflt"
+end)
+setmetatableindex(languages,function(t,k)
+  if k then
+    k=lower(k)
+    if k=="dflt" then
+      return k
+    end
+    local v=rawget(t,k)
+    if v then
+      return v
+    end
+    k=gsub(k," ","")
+    v=rawget(t,v)
+    if v then
+      return v
+    elseif acceptlanguages then
+      report_checks("registering extra language %a",k)
+      rawset(t,k,k)
+      return k
+    end
+  end
+  return "dflt"
+end)
+if setmetatablenewindex then
+  setmetatablenewindex(languages,"ignore")
+  setmetatablenewindex(scripts,"ignore")
+  setmetatablenewindex(baselines,"ignore")
+end
+local function resolve(t,k)
+  if k then
+    k=lower(k)
+    local v=rawget(t,k)
+    if v then
+      return v
+    end
+    k=gsub(k," ","")
+    local v=rawget(t,k)
+    if v then
+      return v
+    end
+    local tag,dd=match(k,"(..)(%d+)")
+    if tag and dd then
+      local v=rawget(t,tag)
+      if v then
+        return v 
+      else
+        local v=rawget(t,tag.."..") 
+        if v then
+          return (gsub(v,"%.%.",tonumber(dd))) 
+        end
+      end
+    end
+  end
+  return k 
+end
+setmetatableindex(features,resolve)
+local function assign(t,k,v)
+  if k and v then
+    v=lower(v)
+    rawset(t,k,v)
+  end
+end
+if setmetatablenewindex then
+  setmetatablenewindex(features,assign)
+end
+local checkers={
+  rand=function(v)
+    return v==true and "random" or v
+  end
+}
+if not storage then
+  return
+end
+local usedfeatures=statistics.usedfeatures or {}
+statistics.usedfeatures=usedfeatures
+table.setmetatableindex(usedfeatures,function(t,k) if k then local v={} t[k]=v return v end end) 
+storage.register("fonts/otf/usedfeatures",usedfeatures,"fonts.handlers.otf.statistics.usedfeatures" )
+local normalizedaxis=otf.readers.helpers.normalizedaxis or function(s) return s end
+function otffeatures.normalize(features)
+  if features then
+    local h={}
+    for key,value in next,features do
+      local k=lower(key)
+      if k=="language" then
+        local v=gsub(lower(value),"[^a-z0-9]","")
+        h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt" 
+      elseif k=="script" then
+        local v=gsub(lower(value),"[^a-z0-9]","")
+        h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" 
+      elseif k=="axis" then
+        h[k]=normalizedaxis(value)
+        if not callbacks.supported.glyph_stream_provider then
+          h.variableshapes=true 
+        end
+      else
+        local uk=usedfeatures[key]
+        local uv=uk[value]
+        if uv then
+        else
+          uv=tonumber(value) 
+          if uv then
+          elseif type(value)=="string" then
+            local b=is_boolean(value)
+            if type(b)=="nil" then
+              uv=lower(value)
+            else
+              uv=b
+            end
+          elseif type(value)=="table" then
+            uv=sequenced(t,",")
+          else
+            uv=value
+          end
+          if not rawget(features,k) then
+            k=rawget(verbosefeatures,k) or k
+          end
+          local c=checkers[k]
+          if c then
+            uv=c(uv) or vc
+          end
+          uk[value]=uv
+        end
+        h[k]=uv
+      end
+    end
+    return h
+  end
+end
+
+end --- [luaotfload, fontloader-2018-09-24.lua scope for “font-ott”] ---
+
+
+do  --- [luaotfload, fontloader-2018-09-24.lua scope for “font-cff” eefa156275ba0ac91aa651a944d35978] ---
+
+if not modules then modules={} end modules ['font-cff']={
+  version=1.001,
+  comment="companion to font-ini.mkiv",
+  author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+  copyright="PRAGMA ADE / ConTeXt Development Team",
+  license="see context related readme files"
+}
+local next,type,tonumber=next,type,tonumber
+local byte,char,gmatch=string.byte,string.char,string.gmatch
+local concat,remove=table.concat,table.remove
+local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max
+local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct
+local lpegmatch=lpeg.match
+local formatters=string.formatters
+local bytetable=string.bytetable
+local readers=fonts.handlers.otf.readers
+local streamreader=readers.streamreader
+local readstring=streamreader.readstring
+local readbyte=streamreader.readcardinal1 
+local readushort=streamreader.readcardinal2 
+local readuint=streamreader.readcardinal3 
+local readulong=streamreader.readcardinal4 
+local setposition=streamreader.setposition
+local getposition=streamreader.getposition
+local readbytetable=streamreader.readbytetable
+directives.register("fonts.streamreader",function()
+  streamreader=utilities.streams
+  readstring=streamreader.readstring
+  readbyte=streamreader.readcardinal1
+  readushort=streamreader.readcardinal2
+  readuint=streamreader.readcardinal3
+  readulong=streamreader.readcardinal4
+  setposition=streamreader.setposition
+  getposition=streamreader.getposition
+  readbytetable=streamreader.readbytetable
+end)
+local setmetatableindex=table.setmetatableindex
+local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end)
+local report=logs.reporter("otf reader","cff")
+local parsedictionaries
+local parsecharstring
+local parsecharstrings
+local resetcharstrings
+local parseprivates
+local startparsing
+local stopparsing
+local defaultstrings={ [0]=
+  ".notdef","space","exclam","quotedbl","numbersign","dollar","percent",
+  "ampersand","quoteright","parenleft","parenright","asterisk","plus",
+  "comma","hyphen","period","slash","zero","one","two","three","four",
+  "five","six","seven","eight","nine","colon","semicolon","less",
+  "equal","greater","question","at","A","B","C","D","E","F","G","H",
+  "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W",
+  "X","Y","Z","bracketleft","backslash","bracketright","asciicircum",
+  "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j",
+  "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y",
+  "z","braceleft","bar","braceright","asciitilde","exclamdown","cent",
+  "sterling","fraction","yen","florin","section","currency",
+  "quotesingle","quotedblleft","guillemotleft","guilsinglleft",
+  "guilsinglright","fi","fl","endash","dagger","daggerdbl",
+  "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase",
+  "quotedblright","guillemotright","ellipsis","perthousand","questiondown",
+  "grave","acute","circumflex","tilde","macron","breve","dotaccent",
+  "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash",
+  "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae",
+  "dotlessi","lslash","oslash","oe","germandbls","onesuperior",
+  "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn",
+  "onequarter","divide","brokenbar","degree","thorn","threequarters",
+  "twosuperior","registered","minus","eth","multiply","threesuperior",
+  "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring",
+  "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave",
+  "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute",
+  "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute",
+  "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron",
+  "aacute","acircumflex","adieresis","agrave","aring","atilde",
+  "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute",
+  "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex",
+  "odieresis","ograve","otilde","scaron","uacute","ucircumflex",
+  "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall",
+  "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall",
+  "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader",
+  "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle",
+  "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle",
+  "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior",
+  "threequartersemdash","periodsuperior","questionsmall","asuperior",
+  "bsuperior","centsuperior","dsuperior","esuperior","isuperior",
+  "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior",
+  "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior",
+  "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall",
+  "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall",
+  "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall",
+  "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall",
+  "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah",
+  "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall",
+  "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall",
+  "Dotaccentsmall","Macronsmall","figuredash","hypheninferior",
+  "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth",
+  "threeeighths","fiveeighths","seveneighths","onethird","twothirds",
+  "zerosuperior","foursuperior","fivesuperior","sixsuperior",
+  "sevensuperior","eightsuperior","ninesuperior","zeroinferior",
+  "oneinferior","twoinferior","threeinferior","fourinferior",
+  "fiveinferior","sixinferior","seveninferior","eightinferior",
+  "nineinferior","centinferior","dollarinferior","periodinferior",
+  "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall",
+  "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall",
+  "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall",
+  "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall",
+  "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall",
+  "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall",
+  "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall",
+  "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003",
+  "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold",
+}
+local cffreaders={
+  readbyte,
+  readushort,
+  readuint,
+  readulong,
+}
+local function readheader(f)
+  local offset=getposition(f)
+  local major=readbyte(f)
+  local header={
+    offset=offset,
+    major=major,
+    minor=readbyte(f),
+    size=readbyte(f),
+  }
+  if major==1 then
+    header.dsize=readbyte(f)  
+  elseif major==2 then
+    header.dsize=readushort(f) 
+  else
+  end
+  setposition(f,offset+header.size)
+  return header
+end
+local function readlengths(f,longcount)
+  local count=longcount and readulong(f) or readushort(f)
+  if count==0 then
+    return {}
+  end
+  local osize=readbyte(f)
+  local read=cffreaders[osize]
+  if not read then
+    report("bad offset size: %i",osize)
+    return {}
+  end
+  local lengths={}
+  local previous=read(f)
+  for i=1,count do
+    local offset=read(f)
+    local length=offset-previous
+    if length<0 then
+      report("bad offset: %i",length)
+      length=0
+    end
+    lengths[i]=length
+    previous=offset
+  end
+  return lengths
+end
+local function readfontnames(f)
+  local names=readlengths(f)
+  for i=1,#names do
+    names[i]=readstring(f,names[i])
+  end
+  return names
+end
+local function readtopdictionaries(f)
+  local dictionaries=readlengths(f)
+  for i=1,#dictionaries do
+    dictionaries[i]=readstring(f,dictionaries[i])
+  end
+  return dictionaries
+end
+local function readstrings(f)
+  local lengths=readlengths(f)
+  local strings=setmetatableindex({},defaultstrings)
+  local index=#defaultstrings
+  for i=1,#lengths do
+    index=index+1
+    strings[index]=readstring(f,lengths[i])
+  end
+  return strings
+end
+do
+  local stack={}
+  local top=0
+  local result={}
+  local strings={}
+  local p_single=P("\00")/function()
+      result.version=strings[stack[top]] or "unset"
+      top=0
+    end+P("\01")/function()
+      result.notice=strings[stack[top]] or "unset"
+      top=0
+    end+P("\02")/function()
+      result.fullname=strings[stack[top]] or "unset"
+      top=0
+    end+P("\03")/function()
+      result.familyname=strings[stack[top]] or "unset"
+      top=0
+    end+P("\04")/function()
+      result.weight=strings[stack[top]] or "unset"
+      top=0
+    end+P("\05")/function()
+      result.fontbbox={ unpack(stack,1,4) }
+      top=0
+    end
++P("\13")/function()
+      result.uniqueid=stack[top]
+      top=0
+    end+P("\14")/function()
+      result.xuid=concat(stack,"",1,top)
+      top=0
+    end+P("\15")/function()
+      result.charset=stack[top]
+      top=0
+    end+P("\16")/function()
+      result.encoding=stack[top]
+      top=0
+    end+P("\17")/function() 
+      result.charstrings=stack[top]
+      top=0
+    end+P("\18")/function()
+      result.private={
+        size=stack[top-1],
+        offset=stack[top],
+      }
+      top=0
+    end+P("\19")/function()
+      result.subroutines=stack[top]
+      top=0 
+    end+P("\20")/function()
+      result.defaultwidthx=stack[top]
+      top=0 
+    end+P("\21")/function()
+      result.nominalwidthx=stack[top]
+      top=0 
+    end
++P("\24")/function() 
+      result.vstore=stack[top]
+      top=0
+    end+P("\25")/function() 
+      result.maxstack=stack[top]
+      top=0
+    end
+  local p_double=P("\12")*(
+    P("\00")/function()
+      result.copyright=stack[top]
+      top=0
+    end+P("\01")/function()
+      result.monospaced=stack[top]==1 and true or false 
+      top=0
+    end+P("\02")/function()
+      result.italicangle=stack[top]
+      top=0
+    end+P("\03")/function()
+      result.underlineposition=stack[top]
+      top=0
+    end+P("\04")/function()
+      result.underlinethickness=stack[top]
+      top=0
+    end+P("\05")/function()
+      result.painttype=stack[top]
+      top=0
+    end+P("\06")/function()
+      result.charstringtype=stack[top]
+      top=0
+    end+P("\07")/function() 
+      result.fontmatrix={ unpack(stack,1,6) }
+      top=0
+    end+P("\08")/function()
+      result.strokewidth=stack[top]
+      top=0
+    end+P("\20")/function()
+      result.syntheticbase=stack[top]
+      top=0
+    end+P("\21")/function()
+      result.postscript=strings[stack[top]] or "unset"
+      top=0
+    end+P("\22")/function()
+      result.basefontname=strings[stack[top]] or "unset"
+      top=0
+    end+P("\21")/function()
+      result.basefontblend=stack[top]
+      top=0
+    end+P("\30")/function()
+      result.cid.registry=strings[stack[top-2]] or "unset"
+      result.cid.ordering=strings[stack[top-1]] or "unset"
+      result.cid.supplement=stack[top]
+      top=0
+    end+P("\31")/function()
+      result.cid.fontversion=stack[top]
+      top=0
+    end+P("\32")/function()
+      result.cid.fontrevision=stack[top]
+      top=0
+    end+P("\33")/function()
+      result.cid.fonttype=stack[top]
+      top=0
+    end+P("\34")/function()
+      result.cid.count=stack[top]
+      top=0
+    end+P("\35")/function()
+      result.cid.uidbase=stack[top]
+      top=0
+    end+P("\36")/function() 
+      result.cid.fdarray=stack[top]
+      top=0
+    end+P("\37")/function() 
+      result.cid.fdselect=stack[top]
+      top=0
+    end+P("\38")/function()
+      result.cid.fontname=strings[stack[top]] or "unset"
+      top=0
+    end
+  )
+  local p_last=P("\x0F")/"0"+P("\x1F")/"1"+P("\x2F")/"2"+P("\x3F")/"3"+P("\x4F")/"4"+P("\x5F")/"5"+P("\x6F")/"6"+P("\x7F")/"7"+P("\x8F")/"8"+P("\x9F")/"9"+P("\xAF")/""+P("\xBF")/""+P("\xCF")/""+P("\xDF")/""+P("\xEF")/""+R("\xF0\xFF")/""
+  local remap={
+    ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0",
+    ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="0.",["\x1B"]="0E",["\x1C"]="0E-",["\x1D"]="0",["\x1E"]="0-",["\x1F"]="0",
+    ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="0.",["\x2B"]="0E",["\x2C"]="0E-",["\x2D"]="0",["\x2E"]="0-",["\x2F"]="0",
+    ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="0.",["\x3B"]="0E",["\x3C"]="0E-",["\x3D"]="0",["\x3E"]="0-",["\x3F"]="0",
+    ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="0.",["\x4B"]="0E",["\x4C"]="0E-",["\x4D"]="0",["\x4E"]="0-",["\x4F"]="0",
+    ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="0.",["\x5B"]="0E",["\x5C"]="0E-",["\x5D"]="0",["\x5E"]="0-",["\x5F"]="0",
+    ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="0.",["\x6B"]="0E",["\x6C"]="0E-",["\x6D"]="0",["\x6E"]="0-",["\x6F"]="0",
+    ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="0.",["\x7B"]="0E",["\x7C"]="0E-",["\x7D"]="0",["\x7E"]="0-",["\x7F"]="0",
+    ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="0.",["\x8B"]="0E",["\x8C"]="0E-",["\x8D"]="0",["\x8E"]="0-",["\x8F"]="0",
+    ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="0.",["\x9B"]="0E",["\x9C"]="0E-",["\x9D"]="0",["\x9E"]="0-",["\x9F"]="0",
+    ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".",
+    ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E",
+    ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-",
+    ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-",
+  }
+  local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0+p_last)/function(n)
+    top=top+1
+    stack[top]=tonumber(n) or 0
+  end
+  local p_byte=C(R("\32\246"))/function(b0)
+    top=top+1
+    stack[top]=byte(b0)-139
+  end
+  local p_positive=C(R("\247\250"))*C(1)/function(b0,b1)
+    top=top+1
+    stack[top]=(byte(b0)-247)*256+byte(b1)+108
+  end
+  local p_negative=C(R("\251\254"))*C(1)/function(b0,b1)
+    top=top+1
+    stack[top]=-(byte(b0)-251)*256-byte(b1)-108
+  end
+  local p_short=P("\28")*C(1)*C(1)/function(b1,b2)
+    top=top+1
+    local n=0x100*byte(b1)+byte(b2)
+    if n>=0x8000 then
+      stack[top]=n-0xFFFF-1
+    else
+      stack[top]=n
+    end
+  end
+  local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4)
+    top=top+1
+    local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4)
+    if n>=0x8000000 then
+      stack[top]=n-0xFFFFFFFF-1
+    else
+      stack[top]=n
+    end
+  end
+  local p_unsupported=P(1)/function(detail)
+    top=0
+  end
+  local p_dictionary=(
+    p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported
+  )^1
+  parsedictionaries=function(data,dictionaries,what)
+    stack={}
+    strings=data.strings
+    for i=1,#dictionaries do
+      top=0
+      result=what=="cff" and {
+        monospaced=false,
+        italicangle=0,
+        underlineposition=-100,
+        underlinethickness=50,
+        painttype=0,
+        charstringtype=2,
+        fontmatrix={ 0.001,0,0,0.001,0,0 },
+        fontbbox={ 0,0,0,0 },
+        strokewidth=0,
+        charset=0,
+        encoding=0,
+        cid={
+          fontversion=0,
+          fontrevision=0,
+          fonttype=0,
+          count=8720,
+        }
+      } or {
+        charstringtype=2,
+        charset=0,
+        vstore=0,
+        cid={
+        },
+      }
+      lpegmatch(p_dictionary,dictionaries[i])
+      dictionaries[i]=result
+    end
+    result={}
+    top=0
+    stack={}
+  end
+  parseprivates=function(data,dictionaries)
+    stack={}
+    strings=data.strings
+    for i=1,#dictionaries do
+      local private=dictionaries[i].private
+      if private and private.data then
+        top=0
+        result={
+          forcebold=false,
+          languagegroup=0,
+          expansionfactor=0.06,
+          initialrandomseed=0,
+          subroutines=0,
+          defaultwidthx=0,
+          nominalwidthx=0,
+          cid={
+          },
+        }
+        lpegmatch(p_dictionary,private.data)
+        private.data=result
+      end
+    end
+    result={}
+    top=0
+    stack={}
+  end
+  local x=0
+  local y=0
+  local width=false
+  local r=0
+  local stems=0
+  local globalbias=0
+  local localbias=0
+  local nominalwidth=0
+  local defaultwidth=0
+  local charset=false
+  local globals=false
+  local locals=false
+  local depth=1
+  local xmin=0
+  local xmax=0
+  local ymin=0
+  local ymax=0
+  local checked=false
+  local keepcurve=false
+  local version=2
+  local regions=false
+  local nofregions=0
+  local region=false
+  local factors=false
+  local axis=false
+  local vsindex=0
+  local function showstate(where)
+    report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top)
+  end
+  local function showvalue(where,value,showstack)
+    if showstack then
+      report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top)
+    else
+      report("%w%-10s : %s",depth*2,where,tostring(value))
+    end
+  end
+  local function xymoveto()
+    if keepcurve then
+      r=r+1
+      result[r]={ x,y,"m" }
+    end
+    if checked then
+      if x>xmax then xmax=x elseif x<xmin then xmin=x end
+      if y>ymax then ymax=y elseif y<ymin then ymin=y end
+    else
+      xmin=x
+      ymin=y
+      xmax=x
+      ymax=y
+      checked=true
+    end
+  end
+  local function xmoveto() 
+    if keepcurve then
+      r=r+1
+      result[r]={ x,y,"m" }
+    end
+    if not checked then
+      xmin=x
+      ymin=y
+      xmax=x
+      ymax=y
+      checked=true
+    elseif x>xmax then
+      xmax=x
+    elseif x<xmin then
+      xmin=x
+    end
+  end
+  local function ymoveto() 
+    if keepcurve then
+      r=r+1
+      result[r]={ x,y,"m" }
+    end
+    if not checked then
+      xmin=x
+      ymin=y
+      xmax=x
+      ymax=y
+      checked=true
+    elseif y>ymax then
+      ymax=y
+    elseif y<ymin then
+      ymin=y
+    end
+  end
+  local function moveto()
+    if trace_charstrings then
+      showstate("moveto")
+    end
+    top=0 
+    xymoveto()
+  end
+  local function xylineto() 
+    if keepcurve then
+      r=r+1
+      result[r]={ x,y,"l" }
+    end
+    if checked then
+      if x>xmax then xmax=x elseif x<xmin then xmin=x end
+      if y>ymax then ymax=y elseif y<ymin then ymin=y end
+    else
+      xmin=x
+      ymin=y
+      xmax=x
+      ymax=y
+      checked=true
+    end
+  end
+  local function xlineto() 
+    if keepcurve then
+      r=r+1
+      result[r]={ x,y,"l" }
+    end
+    if not checked then
+      xmin=x
+      ymin=y
+      xmax=x
+      ymax=y
+      checked=true
+    elseif x>xmax then
+      xmax=x
+    elseif x<xmin then
+      xmin=x
+    end
+  end
+  local function ylineto() 
+    if keepcurve then
+      r=r+1
+      result[r]={ x,y,"l" }
+    end
+    if not checked then
+      xmin=x
+      ymin=y
+      xmax=x
+      ymax=y
+      checked=true
+    elseif y>ymax then
+      ymax=y
+    elseif y<ymin then
+      ymin=y
+    end
+  end
+  local function xycurveto(x1,y1,x2,y2,x3,y3) 
+    if trace_charstrings then
+      showstate("curveto")
+    end
+    if keepcurve then
+      r=r+1
+      result[r]={ x1,y1,x2,y2,x3,y3,"c" }
+    end
+    if checked then
+      if x1>xmax then xmax=x1 elseif x1<xmin then xmin=x1 end
+      if y1>ymax then ymax=y1 elseif y1<ymin then ymin=y1 end
+    else
+      xmin=x1
+      ymin=y1
+      xmax=x1
+      ymax=y1
+      checked=true
+    end
+    if x2>xmax then xmax=x2 elseif x2<xmin then xmin=x2 end
+    if y2>ymax then ymax=y2 elseif y2<ymin then ymin=y2 end
+    if x3>xmax then xmax=x3 elseif x3<xmin then xmin=x3 end
+    if y3>ymax then ymax=y3 elseif y3<ymin then ymin=y3 end
+  end
+  local function rmoveto()
+    if not width then
+      if top>2 then
+        width=stack[1]
+        if trace_charstrings then
+          showvalue("backtrack width",width)
+        end
+      else
+        width=true
+      end
+    end
+    if trace_charstrings then
+      showstate("rmoveto")
+    end
+    x=x+stack[top-1] 
+    y=y+stack[top]  
+    top=0
+    xymoveto()
+  end
+  local function hmoveto()
+    if not width then
+      if top>1 then
+        width=stack[1]
+        if trace_charstrings then
+          showvalue("backtrack width",width)
+        end
+      else
+        width=true
+      end
+    end
+    if trace_charstrings then
+      showstate("hmoveto")
+    end
+    x=x+stack[top] 
+    top=0
+    xmoveto()
+  end
+  local function vmoveto()
+    if not width then
+      if top>1 then
+        width=stack[1]
+        if trace_charstrings then
+          showvalue("backtrack width",width)
+        end
+      else
+        width=true
+      end
+    end
+    if trace_charstrings then
+      showstate("vmoveto")
+    end
+    y=y+stack[top] 
+    top=0
+    ymoveto()
+  end
+  local function rlineto()
+    if trace_charstrings then
+      showstate("rlineto")
+    end
+    for i=1,top,2 do
+      x=x+stack[i]  
+      y=y+stack[i+1] 
+      xylineto()
+    end
+    top=0
+  end
+  local function hlineto() 
+    if trace_charstrings then
+      showstate("hlineto")
+    end
+    if top==1 then
+      x=x+stack[1]
+      xlineto()
+    else
+      local swap=true
+      for i=1,top do
+        if swap then
+          x=x+stack[i]
+          xlineto()
+          swap=false
+        else
+          y=y+stack[i]
+          ylineto()
+          swap=true
+        end
+      end
+    end
+    top=0
+  end
+  local function vlineto() 
+    if trace_charstrings then
+      showstate("vlineto")
+    end
+    if top==1 then
+      y=y+stack[1]
+      ylineto()
+    else
+      local swap=false
+      for i=1,top do
+        if swap then
+          x=x+stack[i]
+          xlineto()
+          swap=false
+        else
+          y=y+stack[i]
+          ylineto()
+          swap=true
+        end
+      end
+    end
+    top=0
+  end
+  local function rrcurveto()
+    if trace_charstrings then
+      showstate("rrcurveto")
+    end
+    for i=1,top,6 do
+      local ax=x+stack[i]  
+      local ay=y+stack[i+1] 
+      local bx=ax+stack[i+2] 
+      local by=ay+stack[i+3] 
+      x=bx+stack[i+4]    
+      y=by+stack[i+5]    
+      xycurveto(ax,ay,bx,by,x,y)
+    end
+    top=0
+  end
+  local function hhcurveto()
+    if trace_charstrings then
+      showstate("hhcurveto")
+    end
+    local s=1
+    if top%2~=0 then
+      y=y+stack[1]      
+      s=2
+    end
+    for i=s,top,4 do
+      local ax=x+stack[i]  
+      local ay=y
+      local bx=ax+stack[i+1] 
+      local by=ay+stack[i+2] 
+      x=bx+stack[i+3]    
+      y=by
+      xycurveto(ax,ay,bx,by,x,y)
+    end
+    top=0
+  end
+  local function vvcurveto()
+    if trace_charstrings then
+      showstate("vvcurveto")
+    end
+    local s=1
+    local d=0
+    if top%2~=0 then
+      d=stack[1]        
+      s=2
+    end
+    for i=s,top,4 do
+      local ax=x+d
+      local ay=y+stack[i]  
+      local bx=ax+stack[i+1] 
+      local by=ay+stack[i+2] 
+      x=bx
+      y=by+stack[i+3]    
+      xycurveto(ax,ay,bx,by,x,y)
+      d=0
+    end
+    top=0
+  end
+  local function xxcurveto(swap)
+    local last=top%4~=0 and stack[top]
+    if last then
+      top=top-1
+    end
+    for i=1,top,4 do
+      local ax,ay,bx,by
+      if swap then
+        ax=x+stack[i]
+        ay=y
+        bx=ax+stack[i+1]
+        by=ay+stack[i+2]
+        y=by+stack[i+3]
+        if last and i+3==top then
+          x=bx+last
+        else
+          x=bx
+        end
+        swap=false
+      else
+        ax=x
+        ay=y+stack[i]
+        bx=ax+stack[i+1]
+        by=ay+stack[i+2]
+        x=bx+stack[i+3]
+        if last and i+3==top then
+          y=by+last
+        else
+          y=by
+        end
+        swap=true
+      end
+      xycurveto(ax,ay,bx,by,x,y)
+    end
+    top=0
+  end
+  local function hvcurveto()
+    if trace_charstrings then
+      showstate("hvcurveto")
+    end
+    xxcurveto(true)
+  end
+  local function vhcurveto()
+    if trace_charstrings then
+      showstate("vhcurveto")
+    end
+    xxcurveto(false)
+  end
+  local function rcurveline()
+    if trace_charstrings then
+      showstate("rcurveline")
+    end
+    for i=1,top-2,6 do
+      local ax=x+stack[i]  
+      local ay=y+stack[i+1] 
+      local bx=ax+stack[i+2] 
+      local by=ay+stack[i+3] 
+      x=bx+stack[i+4] 
+      y=by+stack[i+5] 
+      xycurveto(ax,ay,bx,by,x,y)
+    end
+    x=x+stack[top-1] 
+    y=y+stack[top]  
+    xylineto()
+    top=0
+  end
+  local function rlinecurve()
+    if trace_charstrings then
+      showstate("rlinecurve")
+    end
+    if top>6 then
+      for i=1,top-6,2 do
+        x=x+stack[i]
+        y=y+stack[i+1]
+        xylineto()
+      end
+    end
+    local ax=x+stack[top-5]
+    local ay=y+stack[top-4]
+    local bx=ax+stack[top-3]
+    local by=ay+stack[top-2]
+    x=bx+stack[top-1]
+    y=by+stack[top]
+    xycurveto(ax,ay,bx,by,x,y)
+    top=0
+  end
+  local function flex() 
+    if trace_charstrings then
+      showstate("flex")
+    end
+    local ax=x+stack[1] 
+    local ay=y+stack[2] 
+    local bx=ax+stack[3] 
+    local by=ay+stack[4] 
+    local cx=bx+stack[5] 
+    local cy=by+stack[6] 
+    xycurveto(ax,ay,bx,by,cx,cy)
+    local dx=cx+stack[7] 
+    local dy=cy+stack[8] 
+    local ex=dx+stack[9] 
+    local ey=dy+stack[10] 
+    x=ex+stack[11]    
+    y=ey+stack[12]    
+    xycurveto(dx,dy,ex,ey,x,y)
+    top=0
+  end
+  local function hflex()
+    if trace_charstrings then
+      showstate("hflex")
+    end
+    local ax=x+stack[1] 
+    local ay=y
+    local bx=ax+stack[2] 
+    local by=ay+stack[3] 
+    local cx=bx+stack[4] 
+    local cy=by
+    xycurveto(ax,ay,bx,by,cx,cy)
+    local dx=cx+stack[5] 
+    local dy=by
+    local ex=dx+stack[6] 
+    local ey=y
+    x=ex+stack[7]    
+    xycurveto(dx,dy,ex,ey,x,y)
+    top=0
+  end
+  local function hflex1()
+    if trace_charstrings then
+      showstate("hflex1")
+    end
+    local ax=x+stack[1] 
+    local ay=y+stack[2] 
+    local bx=ax+stack[3] 
+    local by=ay+stack[4] 
+    local cx=bx+stack[5] 
+    local cy=by
+    xycurveto(ax,ay,bx,by,cx,cy)
+    local dx=cx+stack[6] 
+    local dy=by
+    local ex=dx+stack[7] 
+    local ey=dy+stack[8] 
+    x=ex+stack[9]    
+    xycurveto(dx,dy,ex,ey,x,y)
+    top=0
+  end
+  local function flex1()
+    if trace_charstrings then
+      showstate("flex1")
+    end
+    local ax=x+stack[1] 
+    local ay=y+stack[2] 
+    local bx=ax+stack[3] 
+    local by=ay+stack[4] 
+    local cx=bx+stack[5] 
+    local cy=by+stack[6] 
+    xycurveto(ax,ay,bx,by,cx,cy)
+    local dx=cx+stack[7] 
+    local dy=cy+stack[8] 
+    local ex=dx+stack[9] 
+    local ey=dy+stack[10] 
+    if abs(ex-x)>abs(ey-y) then 
+      x=ex+stack[11]
+    else
+      y=ey+stack[11]
+    end
+    xycurveto(dx,dy,ex,ey,x,y)
+    top=0
+  end
+  local function getstem()
+    if top==0 then
+    elseif top%2~=0 then
+      if width then
+        remove(stack,1)
+      else
+        width=remove(stack,1)
+        if trace_charstrings then
+          showvalue("width",width)
+        end
+      end
+      top=top-1
+    end
+    if trace_charstrings then
+      showstate("stem")
+    end
+    stems=stems+top/2
+    top=0
+  end
+  local function getmask()
+    if top==0 then
+    elseif top%2~=0 then
+      if width then
+        remove(stack,1)
+      else
+        width=remove(stack,1)
+        if trace_charstrings then
+          showvalue("width",width)
+        end
+      end
+      top=top-1
+    end
+    if trace_charstrings then
+      showstate(operator==19 and "hintmark" or "cntrmask")
+    end
+    stems=stems+top/2
+    top=0
+    if stems==0 then
+    elseif stems<=8 then
+      return 1
+    else
+      return floor((stems+7)/8)
+    end
+  end
+  local function unsupported(t)
+    if trace_charstrings then
+      showstate("unsupported "..t)
+    end
+    top=0
+  end
+  local function unsupportedsub(t)
+    if trace_charstrings then
+      showstate("unsupported sub "..t)
+    end
+    top=0
+  end
+  local function getstem3()
+    if trace_charstrings then
+      showstate("stem3")
+    end
+    top=0
+  end
+  local function divide()
+    if version==1 then
+      local d=stack[top]
+      top=top-1
+      stack[top]=stack[top]/d
+    end
+  end
+  local function closepath()
+    if version==1 then
+      if trace_charstrings then
+        showstate("closepath")
+      end
+    end
+    top=0
+  end
+  local function hsbw()
+    if version==1 then
+      if trace_charstrings then
+        showstate("dotsection")
+      end
+      width=stack[top]
+    end
+    top=0
+  end
+  local function seac()
+    if version==1 then
+      if trace_charstrings then
+        showstate("seac")
+      end
+    end
+    top=0
+  end
+  local function sbw()
+    if version==1 then
+      if trace_charstrings then
+        showstate("sbw")
+      end
+      width=stack[top-1]
+    end
+    top=0
+  end
+  local function callothersubr()
+    if version==1 then
+      if trace_charstrings then
+        showstate("callothersubr (unsupported)")
+      end
+    end
+    top=0
+  end
+  local function pop()
+    if version==1 then
+      if trace_charstrings then
+        showstate("pop (unsupported)")
+      end
+      top=top+1
+      stack[top]=0 
+    else
+      top=0
+    end
+  end
+  local function setcurrentpoint()
+    if version==1 then
+      if trace_charstrings then
+        showstate("pop (unsupported)")
+      end
+      x=x+stack[top-1]
+      y=y+stack[top]
+    end
+    top=0
+  end
+  local reginit=false
+  local function updateregions(n) 
+    if regions then
+      local current=regions[n] or regions[1]
+      nofregions=#current
+      if axis and n~=reginit then
+        factors={}
+        for i=1,nofregions do
+          local region=current[i]
+          local s=1
+          for j=1,#axis do
+            local f=axis[j]
+            local r=region[j]
+            local start=r.start
+            local peak=r.peak
+            local stop=r.stop
+            if start>peak or peak>stop then
+            elseif start<0 and stop>0 and peak~=0 then
+            elseif peak==0 then
+            elseif f<start or f>stop then
+              s=0
+              break
+            elseif f<peak then
+              s=s*(f-start)/(peak-start)
+            elseif f>peak then
+              s=s*(stop-f)/(stop-peak)
+            else
+            end
+          end
+          factors[i]=s
+        end
+      end
+    end
+    reginit=n
+  end
+  local function setvsindex()
+    local vsindex=stack[top]
+    if trace_charstrings then
+      showstate(formatters["vsindex %i"](vsindex))
+    end
+    updateregions(vsindex)
+    top=top-1
+  end
+  local function blend()
+    local n=stack[top]
+    top=top-1
+    if axis then
+      if trace_charstrings then
+        local t=top-nofregions*n
+        local m=t-n
+        for i=1,n do
+          local k=m+i
+          local d=m+n+(i-1)*nofregions
+          local old=stack[k]
+          local new=old
+          for r=1,nofregions do
+            new=new+stack[d+r]*factors[r]
+          end
+          stack[k]=new
+          showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new))
+        end
+        top=t
+      elseif n==1 then
+        top=top-nofregions
+        local v=stack[top]
+        for r=1,nofregions do
+          v=v+stack[top+r]*factors[r]
+        end
+        stack[top]=v
+      else
+        top=top-nofregions*n
+        local d=top
+        local k=top-n
+        for i=1,n do
+          k=k+1
+          local v=stack[k]
+          for r=1,nofregions do
+            v=v+stack[d+r]*factors[r]
+          end
+          stack[k]=v
+          d=d+nofregions
+        end
+      end
+    else
+    end
+  end
+  local actions={ [0]=unsupported,
+    getstem,
+    unsupported,
+    getstem,
+    vmoveto,
+    rlineto,
+    hlineto,
+    vlineto,
+    rrcurveto,
+    unsupported,
+    unsupported,
+    unsupported,
+    unsupported,
+    hsbw,
+    unsupported,
+    setvsindex,
+    blend,
+    unsupported,
+    getstem,
+    getmask,
+    getmask,
+    rmoveto,
+    hmoveto,
+    getstem,
+    rcurveline,
+    rlinecurve,
+    vvcurveto,
+    hhcurveto,
+    unsupported,
+    unsupported,
+    vhcurveto,
+    hvcurveto,
+  }
+  local subactions={
+    [000]=dotsection,
+    [001]=getstem3,
+    [002]=getstem3,
+    [006]=seac,
+    [007]=sbw,
+    [012]=divide,
+    [016]=callothersubr,
+    [017]=pop,
+    [033]=setcurrentpoint,
+    [034]=hflex,
+    [035]=flex,
+    [036]=hflex1,
+    [037]=flex1,
+  }
+  local c_endchar=char(14)
+  local passon do
+    local rshift=bit32.rshift
+    local band=bit32.band
+    local round=math.round
+    local encode=table.setmetatableindex(function(t,i)
+      for i=-2048,-1130 do
+        t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+      end
+      for i=-1131,-108 do
+        local v=0xFB00-i-108
+        t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF))
+      end
+      for i=-107,107 do
+        t[i]=char(i+139)
+      end
+      for i=108,1131 do
+        local v=0xF700+i-108
+        t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF))
+      end
+      for i=1132,2048 do
+        t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+      end
+      return t[i]
+    end)
+    local function setvsindex()
+      local vsindex=stack[top]
+      updateregions(vsindex)
+      top=top-1
+    end
+    local function blend()
+      local n=stack[top]
+      top=top-1
+      if not axis then
+      elseif n==1 then
+        top=top-nofregions
+        local v=stack[top]
+        for r=1,nofregions do
+          v=v+stack[top+r]*factors[r]
+        end
+        stack[top]=round(v)
+      else
+        top=top-nofregions*n
+        local d=top
+        local k=top-n
+        for i=1,n do
+          k=k+1
+          local v=stack[k]
+          for r=1,nofregions do
+            v=v+stack[d+r]*factors[r]
+          end
+          stack[k]=round(v)
+          d=d+nofregions
+        end
+      end
+    end
+    passon=function(operation)
+      if operation==15 then
+        setvsindex()
+      elseif operation==16 then
+        blend()
+      else
+        for i=1,top do
+          r=r+1
+          result[r]=encode[stack[i]]
+        end
+        r=r+1
+        result[r]=char(operation) 
+        top=0
+      end
+    end
+  end
+  local process
+  local function call(scope,list,bias) 
+    depth=depth+1
+    if top==0 then
+      showstate(formatters["unknown %s call"](scope))
+      top=0
+    else
+      local index=stack[top]+bias
+      top=top-1
+      if trace_charstrings then
+        showvalue(scope,index,true)
+      end
+      local tab=list[index]
+      if tab then
+        process(tab)
+      else
+        showstate(formatters["unknown %s call %i"](scope,index))
+        top=0
+      end
+    end
+    depth=depth-1
+  end
+  local justpass=false
+  process=function(tab)
+    local i=1
+    local n=#tab
+    while i<=n do
+      local t=tab[i]
+      if t>=32 then
+        top=top+1
+        if t<=246 then
+          stack[top]=t-139
+          i=i+1
+        elseif t<=250 then
+          stack[top]=t*256-63124+tab[i+1]
+          i=i+2
+        elseif t<=254 then
+          stack[top]=-t*256+64148-tab[i+1]
+          i=i+2
+        else
+          local n=0x100*tab[i+1]+tab[i+2]
+          if n>=0x8000 then
+            stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF
+          else
+            stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF
+          end
+          i=i+5
+        end
+      elseif t==28 then
+        top=top+1
+        local n=0x100*tab[i+1]+tab[i+2]
+        if n>=0x8000 then
+          stack[top]=n-0x10000
+        else
+          stack[top]=n
+        end
+        i=i+3
+      elseif t==11 then 
+        if trace_charstrings then
+          showstate("return")
+        end
+        return
+      elseif t==10 then
+        call("local",locals,localbias) 
+        i=i+1
+      elseif t==14 then 
+        if width then
+        elseif top>0 then
+          width=stack[1]
+          if trace_charstrings then
+            showvalue("width",width)
+          end
+        else
+          width=true
+        end
+        if trace_charstrings then
+          showstate("endchar")
+        end
+        return
+      elseif t==29 then
+        call("global",globals,globalbias) 
+        i=i+1
+      elseif t==12 then
+        i=i+1
+        local t=tab[i]
+        local a=subactions[t]
+        if a then
+          a(t)
+        else
+          if trace_charstrings then
+            showvalue("<subaction>",t)
+          end
+          top=0
+        end
+        i=i+1
+      elseif justpass then
+        passon(t)
+        i=i+1
+      else
+        local a=actions[t]
+        if a then
+          local s=a(t)
+          if s then
+            i=i+s+1
+          else
+            i=i+1
+          end
+        else
+          if trace_charstrings then
+            showvalue("<action>",t)
+          end
+          top=0
+          i=i+1
+        end
+      end
+    end
+  end
+  local function setbias(globals,locals)
+    if version==1 then
+      return
+        false,
+        false
+    else
+      local g,l=#globals,#locals
+      return
+        ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1,
+        ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1
+    end
+  end
+  local function processshape(tab,index)
+    tab=bytetable(tab)
+    x=0
+    y=0
+    width=false
+    r=0
+    top=0
+    stems=0
+    result={} 
+    xmin=0
+    xmax=0
+    ymin=0
+    ymax=0
+    checked=false
+    if trace_charstrings then
+      report("glyph: %i",index)
+      report("data : % t",tab)
+    end
+    if regions then
+      updateregions(vsindex)
+    end
+    process(tab)
+    local boundingbox={
+      round(xmin),
+      round(ymin),
+      round(xmax),
+      round(ymax),
+    }
+    if width==true or width==false then
+      width=defaultwidth
+    else
+      width=nominalwidth+width
+    end
+    local glyph=glyphs[index] 
+    if justpass then
+      r=r+1
+      result[r]=c_endchar
+      local stream=concat(result)
+      if glyph then
+        glyph.stream=stream
+      else
+        glyphs[index]={ stream=stream }
+      end
+    elseif glyph then
+      glyph.segments=keepcurve~=false and result or nil
+      glyph.boundingbox=boundingbox
+      if not glyph.width then
+        glyph.width=width
+      end
+      if charset and not glyph.name then
+        glyph.name=charset[index]
+      end
+    elseif keepcurve then
+      glyphs[index]={
+        segments=result,
+        boundingbox=boundingbox,
+        width=width,
+        name=charset and charset[index] or nil,
+      }
+    else
+      glyphs[index]={
+        boundingbox=boundingbox,
+        width=width,
+        name=charset and charset[index] or nil,
+      }
+    end
+    if trace_charstrings then
+      report("width      : %s",tostring(width))
+      report("boundingbox: % t",boundingbox)
+    end
+  end
+  startparsing=function(fontdata,data,streams)
+    reginit=false
+    axis=false
+    regions=data.regions
+    justpass=streams==true
+    if regions then
+      regions={ regions } 
+      axis=data.factors or false
+    end
+  end
+  stopparsing=function(fontdata,data)
+    stack={}
+    glyphs=false
+    result={}
+    top=0
+    locals=false
+    globals=false
+    strings=false
+  end
+  local function setwidths(private)
+    if not private then
+      return 0,0
+    end
+    local privatedata=private.data
+    if not privatedata then
+      return 0,0
+    end
+    return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0
+  end
+  parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams)
+    local dictionary=data.dictionaries[1]
+    local charstrings=dictionary.charstrings
+    keepcurve=doshapes
+    version=tversion
+    strings=data.strings
+    globals=data.routines or {}
+    locals=dictionary.subroutines or {}
+    charset=dictionary.charset
+    vsindex=dictionary.vsindex or 0
+    glyphs=glphs or {}
+    globalbias,localbias=setbias(globals,locals)
+    nominalwidth,defaultwidth=setwidths(dictionary.private)
+    startparsing(fontdata,data,streams)
+    for index=1,#charstrings do
+      processshape(charstrings[index],index-1)
+      charstrings[index]=nil 
+    end
+    stopparsing(fontdata,data)
+    return glyphs
+  end
+  parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion)
+    keepcurve=doshapes
+    version=tversion
+    strings=data.strings
+    globals=data.routines or {}
+    locals=dictionary.subroutines or {}
+    charset=false
+    vsindex=dictionary.vsindex or 0
+    glyphs=glphs or {}
+    globalbias,localbias=setbias(globals,locals)
+    nominalwidth,defaultwidth=setwidths(dictionary.private)
+    processshape(tab,index-1)
+  end
+end
+local function readglobals(f,data)
+  local routines=readlengths(f)
+  for i=1,#routines do
+    routines[i]=readbytetable(f,routines[i])
+  end
+  data.routines=routines
+end
+local function readencodings(f,data)
+  data.encodings={}
+end
+local function readcharsets(f,data,dictionary)
+  local header=data.header
+  local strings=data.strings
+  local nofglyphs=data.nofglyphs
+  local charsetoffset=dictionary.charset
+  if charsetoffset and charsetoffset~=0 then
+    setposition(f,header.offset+charsetoffset)
+    local format=readbyte(f)
+    local charset={ [0]=".notdef" }
+    dictionary.charset=charset
+    if format==0 then
+      for i=1,nofglyphs do
+        charset[i]=strings[readushort(f)]
+      end
+    elseif format==1 or format==2 then
+      local readcount=format==1 and readbyte or readushort
+      local i=1
+      while i<=nofglyphs do
+        local sid=readushort(f)
+        local n=readcount(f)
+        for s=sid,sid+n do
+          charset[i]=strings[s]
+          i=i+1
+          if i>nofglyphs then
+            break
+          end
+        end
+      end
+    else
+      report("cff parser: unsupported charset format %a",format)
+    end
+  else
+    dictionary.nocharset=true
+    dictionary.charset=nil
+  end
+end
+local function readprivates(f,data)
+  local header=data.header
+  local dictionaries=data.dictionaries
+  local private=dictionaries[1].private
+  if private then
+    setposition(f,header.offset+private.offset)
+    private.data=readstring(f,private.size)
+  end
+end
+local function readlocals(f,data,dictionary)
+  local header=data.header
+  local private=dictionary.private
+  if private then
+    local subroutineoffset=private.data.subroutines
+    if subroutineoffset~=0 then
+      setposition(f,header.offset+private.offset+subroutineoffset)
+      local subroutines=readlengths(f)
+      for i=1,#subroutines do
+        subroutines[i]=readbytetable(f,subroutines[i])
+      end
+      dictionary.subroutines=subroutines
+      private.data.subroutines=nil
+    else
+      dictionary.subroutines={}
+    end
+  else
+    dictionary.subroutines={}
+  end
+end
+local function readcharstrings(f,data,what)
+  local header=data.header
+  local dictionaries=data.dictionaries
+  local dictionary=dictionaries[1]
+  local stringtype=dictionary.charstringtype
+  local offset=dictionary.charstrings
+  if type(offset)~="number" then
+  elseif stringtype==2 then
+    setposition(f,header.offset+offset)
+    local charstrings=readlengths(f,what=="cff2")
+    local nofglyphs=#charstrings
+    for i=1,nofglyphs do
+      charstrings[i]=readstring(f,charstrings[i])
+    end
+    data.nofglyphs=nofglyphs
+    dictionary.charstrings=charstrings
+  else
+    report("unsupported charstr type %i",stringtype)
+    data.nofglyphs=0
+    dictionary.charstrings={}
+  end
+end
+local function readcidprivates(f,data)
+  local header=data.header
+  local dictionaries=data.dictionaries[1].cid.dictionaries
+  for i=1,#dictionaries do
+    local dictionary=dictionaries[i]
+    local private=dictionary.private
+    if private then
+      setposition(f,header.offset+private.offset)
+      private.data=readstring(f,private.size)
+    end
+  end
+  parseprivates(data,dictionaries)
+end
+readers.parsecharstrings=parsecharstrings 
+local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)

@@ Diff output truncated at 1234567 characters. @@


More information about the tex-live-commits mailing list