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 = string.format, table.insert
local type, next = type, next

-- we assume that the other otf stuff is loaded already

local trace_loading = false  trackers.register("otf.loading", function(v) trace_loading = v end)

local fonts = fonts
local otf   = fonts.otf

local report_otf = logs.new("load otf")

-- instead of "script = "DFLT", langs = { 'dflt' }" we now use wildcards (we used to
-- have always); some day we can write a "force always when true" trick for other
-- features as well
--
-- we could have a tnum variant as well

-- In the userdata interface we can not longer tweak the loaded font as
-- conveniently as before. For instance, instead of pushing extra data in
-- in the table using the original structure, we now have to operate on
-- the mkiv representation. And as the fontloader interface is modelled
-- after fontforge we cannot change that one too much either.

local extra_lists = {
    tlig = {
        {
            endash        = "hyphen hyphen",
            emdash        = "hyphen hyphen hyphen",
            quotedblleft  = "quoteleft quoteleft",
            quotedblright = "quoteright quoteright",
            quotedblleft  = "grave grave",
            quotedblright = "quotesingle quotesingle",
            quotedblbase  = "comma comma",
            exclamdown    = "exclam grave",
            questiondown  = "question grave",
            guillemotleft = "less less",
            guillemotright= "greater greater",
        },
    },
    trep = {
        {
            [0x0022] = 0x201D,
            [0x0027] = 0x2019,
            [0x0060] = 0x2018,
        },
    },
    anum = {
        { -- arabic
            [0x0030] = 0x0660,
            [0x0031] = 0x0661,
            [0x0032] = 0x0662,
            [0x0033] = 0x0663,
            [0x0034] = 0x0664,
            [0x0035] = 0x0665,
            [0x0036] = 0x0666,
            [0x0037] = 0x0667,
            [0x0038] = 0x0668,
            [0x0039] = 0x0669,
        },
        { -- persian
            [0x0030] = 0x06F0,
            [0x0031] = 0x06F1,
            [0x0032] = 0x06F2,
            [0x0033] = 0x06F3,
            [0x0034] = 0x06F4,
            [0x0035] = 0x06F5,
            [0x0036] = 0x06F6,
            [0x0037] = 0x06F7,
            [0x0038] = 0x06F8,
            [0x0039] = 0x06F9,
        },
    },
}

local extra_features = { -- maybe just 1..n so that we prescribe order
    tlig = {
        {
            features  = { ["*"] = { ["*"] = true } },
            name      = "ctx_tlig_1",
            subtables = { "ctx_tlig_1_s" },
            type      = "gsub_ligature",
            flags     = { },
        },
    },
    trep = {
        {
            features  = { ["*"] = { ["*"] = true } },
            name      = "ctx_trep_1",
            subtables = { "ctx_trep_1_s" },
            type      = "gsub_single",
            flags     = { },
        },
    },
    anum = {
        {
            features  = { arab = { FAR = true, dflt = true } },
            name      = "ctx_anum_1",
            subtables = { "ctx_anum_1_s" },
            type      = "gsub_single",
            flags     = { },
        },
        {
            features  = { arab = { FAR = true } },
            name      = "ctx_anum_2",
            subtables = { "ctx_anum_2_s" },
            type      = "gsub_single",
            flags     = { },
        },
    },
}

local function enhancedata(data,filename,raw)
    local luatex = data.luatex
    local lookups = luatex.lookups
    local sequences = luatex.sequences
    local glyphs = data.glyphs
    local indices = luatex.indices
    local gsubfeatures = luatex.features.gsub
    for kind, specifications in next, extra_features do
        if gsub and gsub[kind] then
            -- already present
        else
            local done = 0
            for s=1,#specifications do
                local added = false
                local specification = specifications[s]
                local features, subtables = specification.features, specification.subtables
                local name, type, flags = specification.name, specification.type, specification.flags
                local full = subtables[1]
                local list = extra_lists[kind][s]
                if type == "gsub_ligature" then
                    -- inefficient loop
                    for unicode, index in next, indices do
                        local glyph = glyphs[index]
                        local ligature = list[glyph.name]
                        if ligature then
                            if glyph.slookups then
                                glyph.slookups     [full] = { "ligature", ligature, glyph.name }
                            else
                                glyph.slookups = { [full] = { "ligature", ligature, glyph.name } }
                            end
                            done, added = done+1, true
                        end
                    end
                elseif type == "gsub_single" then
                    -- inefficient loop
                    for unicode, index in next, indices do
                        local glyph = glyphs[index]
                        local r = list[unicode]
                        if r then
                            local replacement = indices[r]
                            if replacement and glyphs[replacement] then
                                if glyph.slookups then
                                    glyph.slookups     [full] = { "substitution", glyphs[replacement].name }
                                else
                                    glyph.slookups = { [full] = { "substitution", glyphs[replacement].name } }
                                end
                                done, added = done+1, true
                            end
                        end
                    end
                end
                if added then
                    sequences[#sequences+1] = {
                        chain     = 0,
                        features  = { [kind] = features },
                        flags     = flags,
                        name      = name,
                        subtables = subtables,
                        type      = type,
                    }
                    -- register in metadata (merge as there can be a few)
                    if not gsubfeatures then
                        gsubfeatures = { }
                        luatex.features.gsub = gsubfeatures
                    end
                    local k = gsubfeatures[kind]
                    if not k then
                        k = { }
                        gsubfeatures[kind] = k
                    end
                    for script, languages in next, features 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
            if done > 0 then
                if trace_loading then
                    report_otf("enhance: registering %s feature (%s glyphs affected)",kind,done)
                end
            end
        end
    end
end

otf.enhancers.register("check extra features",enhancedata)

local features = otf.tables.features

features['tlig'] = 'TeX Ligatures'
features['trep'] = 'TeX Replacements'
features['anum'] = 'Arabic Digits'

local registerbasesubstitution = otf.features.registerbasesubstitution

registerbasesubstitution('tlig')
registerbasesubstitution('trep')
registerbasesubstitution('anum')

-- the functionality is defined elsewhere

local initializers        = fonts.initializers
local common_initializers = initializers.common
local base_initializers   = initializers.base.otf
local node_initializers   = initializers.node.otf

base_initializers.equaldigits = common_initializers.equaldigits
node_initializers.equaldigits = common_initializers.equaldigits

base_initializers.lineheight  = common_initializers.lineheight
node_initializers.lineheight  = common_initializers.lineheight

base_initializers.compose     = common_initializers.compose
node_initializers.compose     = common_initializers.compose