if not modules then modules = { } end modules['s-math-characters'] = {
    version   = 1.001,
    comment   = "companion to s-math-characters.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

-- This is one of the oldest cld files but I'm not going to clean it up.

moduledata.math            = moduledata.math            or { }
moduledata.math.characters = moduledata.math.characters or { }

local concat = table.concat
local lower = string.lower
local utfchar = utf.char
local round = math.round

local fontdata = fonts.hashes.identifiers
local chardata = characters.data

local no_description = "no description, private to font"

local limited       = true
local fillinthegaps = true
local upperlimit    = 0x0007F
local upperlimit    = 0xF0000

local f_unicode     = string.formatters["%U"]
local f_slot        = string.formatters["%s/%0X"]

function moduledata.math.characters.showlist(specification)
    specification = interfaces.checkedspecification(specification)
    local id   = specification.number -- or specification.id
    local list = specification.list
    if not id then
        id = font.current()
    end
    if list == "" then
        list = nil
    end
    local tfmdata      = fontdata[id]
    local characters   = tfmdata.characters
    local descriptions = tfmdata.descriptions
    local resources    = tfmdata.resources
    local lookuptypes  = resources.lookuptypes
    local virtual      = tfmdata.properties.virtualized
    local names        = { }
    local gaps         = mathematics.gaps
    local sorted       = { }
    if type(list) == "string" then
        sorted = utilities.parsers.settings_to_array(list)
    elseif type(list) == "table" then
        sorted = list
    elseif fillinthegaps then
        sorted = table.keys(characters)
        for k, v in next, gaps do
            if characters[v] then
                sorted[#sorted+1] = k
            end
        end
        table.sort(sorted)
    else
        sorted = table.sortedkeys(characters)
    end
    if virtual then
        for k, v in ipairs(tfmdata.fonts) do
            local id = v.id
            local name = fontdata[id].properties.name
            names[k] = (name and file.basename(name)) or id
        end
    end
    context.showmathcharactersstart()
    for _, unicode in next, sorted do
        if not limited or unicode < upperlimit then
            local code = gaps[unicode] or unicode
            local char = characters[code]
            local desc = descriptions[code]
            local info = chardata[code]
            if char then
                local next_sizes  = char.next
                local v_variants  = char.vert_variants
                local h_variants  = char.horiz_variants
                local commands    = char.commands
                local slookups    = desc and desc.slookups
                local mlookups    = desc and desc.mlookups
                local mathclass   = info.mathclass
                local mathspec    = info.mathspec
                local mathsymbol  = info.mathsymbol
                local description = info.description or no_description
                context.showmathcharactersstartentry()
                context.showmathcharactersreference(f_unicode(unicode))
                context.showmathcharactersentryhexdectit(f_unicode(code),code,lower(description))
                context.showmathcharactersentrywdhtdpic(round(char.width or 0),round(char.height or 0),round(char.depth or 0),round(char.italic or 0))
                if virtual and commands then
                    local t = { }
                    for i=1,#commands do
                        local ci = commands[i]
                        if ci[1] == "slot" then
                            local fnt, idx = ci[2], ci[3]
                            t[#t+1] = f_slot(names[fnt] or fnt,idx)
                        end
                    end
                    if #t > 0 then
                        context.showmathcharactersentryresource(concat(t,", "))
                    end
                end
                if mathclass or mathspec then
                    context.showmathcharactersstartentryclassspec()
                    if mathclass then
                        context.showmathcharactersentryclassname(mathclass,info.mathname or "no name")
                    end
                    if mathspec then
                        for i=1,#mathspec do
                            local mi = mathspec[i]
                            context.showmathcharactersentryclassname(mi.class,mi.name or "no name")
                        end
                    end
                    context.showmathcharactersstopentryclassspec()
                end
                if mathsymbol then
                    context.showmathcharactersentrysymbol(f_unicode(mathsymbol),mathsymbol)
                end
                if next_sizes then
                    local n, done = 0, { }
                    context.showmathcharactersstartnext()
                    while next_sizes do
                        n = n + 1
                        if done[next_sizes] then
                            context.showmathcharactersnextcycle(n)
                            break
                        else
                            done[next_sizes] = true
                            context.showmathcharactersnextentry(n,f_unicode(next_sizes),next_sizes)
                            next_sizes = characters[next_sizes]
                            v_variants = next_sizes.vert_variants  or v_variants
                            h_variants = next_sizes.horiz_variants or h_variants
                            if next_sizes then
                                next_sizes = next_sizes.next
                            end
                        end
                    end
                    context.showmathcharactersstopnext()
                    if h_variants or v_variants then
                        context.showmathcharactersbetweennextandvariants()
                    end
                end
                if h_variants then
                    context.showmathcharactersstarthvariants()
                    for i=1,#h_variants do -- we might go top-down in the original
                        local vi = h_variants[i]
                        context.showmathcharactershvariantsentry(i,f_unicode(vi.glyph),vi.glyph)
                    end
                    context.showmathcharactersstophvariants()
                elseif v_variants then
                    context.showmathcharactersstartvvariants()
                    for i=1,#v_variants do
                        local vi = v_variants[#v_variants-i+1]
                        context.showmathcharactersvvariantsentry(i,f_unicode(vi.glyph),vi.glyph)
                    end
                    context.showmathcharactersstopvvariants()
                end
                if slookups or mlookups then
                    local variants = { }
                    if slookups then
                        for lookupname, lookupdata in next, slookups do
                            local lookuptype = lookuptypes[lookupname]
                            if lookuptype == "substitution" then
                                variants[lookupdata] = "sub"
                            elseif lookuptype == "alternate" then
                                for i=1,#lookupdata do
                                    variants[lookupdata[i]] = "alt"
                                end
                            end
                        end
                    end
                    if mlookups then
                        for lookupname, lookuplist in next, mlookups do
                            local lookuptype = lookuptypes[lookupname]
                            for i=1,#lookuplist do
                                local lookupdata = lookuplist[i]
                                local lookuptype = lookuptypes[lookupname]
                                if lookuptype == "substitution" then
                                    variants[lookupdata] = "sub"
                                elseif lookuptype == "alternate" then
                                    for i=1,#lookupdata do
                                        variants[lookupdata[i]] = "alt"
                                    end
                                end
                            end
                        end
                    end
                    context.showmathcharactersstartlookupvariants()
                    local i = 0
                    for variant, lookuptype in table.sortedpairs(variants) do
                        i = i + 1
                        context.showmathcharacterslookupvariant(i,f_unicode(variant),variant,lookuptype)
                    end
                    context.showmathcharactersstoplookupvariants()
                end
                context.showmathcharactersstopentry()
            end
        end
    end
    context.showmathcharactersstop()
end
