if not modules then modules = { } end modules ['char-ini'] = { version = 1.001, comment = "companion to char-ini.tex", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } utf = utf or unicode.utf tex = tex or { } local format = string.format --[[ldx--
This module implements some methods and creates additional datastructured
from the big character table that we use for all kind of purposes:
At this point we assume that the big data table is loaded. From this table we derive a few more.
--ldx]]-- -- used ? characters.context.unicodes = characters.context.unicodes or { } characters.context.utfcodes = characters.context.utfcodes or { } characters.context.enccodes = characters.context.enccodes or { } characters.context.fallbacks = characters.context.fallbacks or { } function characters.context.rehash() local unicodes, utfcodes, enccodes, fallbacks, utfchar = characters.context.unicodes, characters.context.utfcodes, characters.context.enccodes, characters.context.fallbacks, utf.char for k,v in pairs(characters.data) do local contextname, adobename, specials = v.contextname, v.adobename, v.specials if contextname then local slot = v.unicodeslot unicodes[contextname] = slot utfcodes[contextname] = utfchar(slot) end local encname = adobename or contextname if encname then enccodes[encname] = k end if specials and specials[1] == "compat" and specials[2] == 0x0020 and specials[3] then local s = specials[3] fallbacks[k] = s fallbacks[s] = k end end for name,code in pairs(characters.synonyms) do if not enccodes[name] then enccodes[name] = code end end end --[[ldx--The
Instead of using a
Setting the lccodes is also done in a loop over the data table.
--ldx]]-- function characters.setcodes() local flush, tc, format = tex.sprint, tex.ctxcatcodes, string.format for code, chr in pairs(characters.data) do local cc = chr.category if cc == 'll' or cc == 'lu' or cc == 'lt' then local lc, uc = chr.lccode, chr.uccode if not lc then chr.lccode, lc = code, code end if not uc then chr.uccode, uc = code, code end flush(tc, format("\\setcclcuc %i %i %i ",code,lc,uc)) end end end --[[ldx--Next comes a whole series of helper methods. These are (will be) part
of the official
This converts a string (if given) into a number.
--ldx]]-- function characters.number(n) if type(n) == "string" then return tonumber(n,16) else return n end end --[[ldx--Checking for valid characters.
--ldx]]-- function characters.is_valid(s) return s or "" end function characters.checked(s, default) return s or default end characters.valid = characters.is_valid --[[ldx--The next method is used when constructing the main table, although nowadays we do this in one step. The index can be a string or a number.
--ldx]]-- function characters.define(c) characters.data[characters.number(c.unicodeslot)] = c end --[[ldx-- --ldx]]-- -- set a table entry; index is number (can be different from unicodeslot) function characters.set(n, c) characters.data[characters.number(n)] = c end --[[ldx--Get a table entry happens by number. Keep in mind that the unicodeslot can be different (not likely).
--ldx]]-- function characters.get(n) return characters.data[characters.number(n)] end --[[ldx--A couple of convenience methods. Beware, these are not that fast due to the checking.
--ldx]]-- function characters.hexindex(n) return format("%04X", characters.valid(characters.data[characters.number(n)].unicodeslot)) end function characters.contextname(n) return characters.valid(characters.data[characters.number(n)].contextname) end function characters.adobename(n) return characters.valid(characters.data[characters.number(n)].adobename) end function characters.description(n) return characters.valid(characters.data[characters.number(n)].description) end function characters.category(n) return characters.valid(characters.data[characters.number(n)].category) end --[[ldx--Requesting lower and uppercase codes:
--ldx]]-- function characters.uccode(n) return characters.data[n].uccode or n end function characters.lccode(n) return characters.data[n].lccode or n end function characters.flush(n) local c = characters.data[n] if c and c.contextname then tex.sprint(tex.texcatcodes, "\\"..c.contextname) else tex.sprint(unicode.utf8.char(n)) end end function characters.shape(n) local shcode = characters.data[n].shcode if not shcode then return n, nil elseif type(shcode) == "table" then return shcode[1], shcode[#shcode] else return shcode, nil end end --[[ldx--Categories play an important role, so here are some checkers.
--ldx]]-- function characters.is_of_category(token,category) if type(token) == "string" then return characters.data[utf.byte(token)].category == category else return characters.data[token].category == category end end function characters.i_is_of_category(i,category) -- by index (number) local cd = characters.data[i] return cd and cd.category == category end function characters.n_is_of_category(n,category) -- by name (string) local cd = characters.data[utf.byte(n)] return cd and cd.category == category end --[[ldx--The following code is kind of messy. It is used to generate the right unicode reference tables.
--ldx]]-- function characters.setpdfunicodes() --~ local flush, tc, sf = tex.sprint, tex.ctxcatcodes, string.format --~ for _,v in pairs(characters.data) do --~ if v.adobename then --~ flush(tc,sf("\\pdfglyphtounicode{%s}{%04X}", v.adobename, v.unicodeslot)) --~ end --~ end end --[[ldx--The next method generates a table for good old