#!/usr/bin/env texlua -------------------------------------------------------------------------------- -- FILE: cyrillicnumbers.lua -- USAGE: called by t-cyrillicnumbers.mkiv -- DESCRIPTION: part of the Cyrillic Numbers module for ConTeXt -- REQUIREMENTS: recent ConTeXt MkIV and LuaTeX -- AUTHOR: Philipp Gesang (phg), -- VERSION: hg tip -- CREATED: 2011-11-29 10:06:00+0100 -------------------------------------------------------------------------------- -- --- read this first: --- --- Жолобов, О. Ф.: *Числительные*. In: *Историческая грамматика древнерусского --- языка*, vol. 4, Moskva 2006, pp. 58--63 --- --- Trunte, Nikolaos H.: *Altkirchenslavisch*. In: *Словѣньскъи ѩꙁъікъ. --- Ein praktisches Lehrbuch des Kirchenslavischen in 30 --- Lektionen. Zugleich eine Einführung in die slavische --- Philologie*, vol. 1, München ⁵2005, pp. 161ff. --- or have a glance at these: --- http://www.pravpiter.ru/zads/n018/ta013.htm --- http://www.uni-giessen.de/partosch/eurotex99/berdnikov2.pdf --- local iowrite = io.write local mathceil = math.ceil local mathfloor = math.floor local tableconcat = table.concat local tablemaxn = table.maxn local tableinsert = table.insert local utf8char = unicode.utf8.char local utf8len = unicode.utf8.len local utfupper = unicode.utf8.upper local cyrnum = { placetitlo = "font", titlolocation = "final", -- above final digit titlospan = 3, -- only with mp drawdots = true, debug = false, } thirddata = thirddata or { } thirddata.cyrnum = cyrnum local dbgpfx = "[cyrnum]" local dbg = function (...) if cyrnum.debug then local args = {...} if type(args[1]) == "table" then args = args[1] end iowrite(dbgpfx) for i=1, #args do local this = args[i] local tthis = type(this) iowrite" " if tthis == "number" or tthis == "string" then iowrite(this) else iowrite(tostring(this)) end end iowrite"\n" end end local cyrillic_numerals = { { "а", "в", "г", "д", "е", "ѕ", "з", "и", "ѳ", }, { "і", "к", "л", "м", "н", "ѯ", "о", "п", "ч", }, { "р", "с", "т", "у", "ф", "х", "ѱ", "ѡ", "ц", }, } local cyrillic_1k = "҂" local cyrillic_100k = utf8char(0x488) -- combining hundred thousands sign local cyrillic_1m = utf8char(0x489) -- combining million sign local cyrillic_titlo = utf8char(0x483) -- combining titlo --local concat_cyrillic_nums = function (chars, upper) -- dbg(chars) -- local nchars, result = tablemaxn(chars), "" -- --if cyrnum.placetitlo and cyrnum.titlomode == "fm" then -- above central char -- -- dbg("char cnt", nchars) -- -- dbg("insert pos", mathceil(nchars/2)) -- -- tableinsert(chars, mathceil(nchars/2), cyrillic_titlo) -- --end -- for i=#chars, 1, -1 do -- local this = chars[i] -- if this then -- if upper then this = utfupper(this) end -- if i > 3 then -- result = result .. cyrillic_1k .. this -- else -- result = result .. this -- end -- end -- end -- if cyrnum.placetitlo and cyrnum.titlomode == "fl" then -- take titlo from font, place it after / above last char -- result = result .. cyrillic_titlo -- end -- return result --end local digits_only = function (list) local result = { } for i=1, tablemaxn(list) do local elm = list[i] if type(elm) == "string" then result[#result+1] = elm end end return result end local lreverse = function(list)local r={}for i=tablemaxn(list),1,-1 do r[#r+1]=list[i]end return r end local start_titlo, stop_titlo = [[\cyrnumdrawtitlo{]], "}" local titlofuncs = { font = function (list) if cyrnum.titlolocation == "final" then list[#list+1] = cyrillic_titlo else -- “middle” or whatever local pos = mathceil(tablemaxn(list)/2) tableinsert(list, mathceil(tablemaxn(list)/2), cyrillic_titlo) end return lreverse(list) end, mp = function (list) local result = { start_titlo } for i=tablemaxn(list), 1, -1 do result[#result+1] = list[i] end result[#result+1] = stop_titlo return result end, no = function (x) return x end, } local concat_cyrillic_nums = function (list, upper) local result = "" local digits = digits_only(list) -- strip placeholders local nlist, ndigits = tablemaxn(list), tablemaxn(digits) dbg(list) dbg(digits) local titlo = titlofuncs[cyrnum.placetitlo] if titlo then result = tableconcat(titlo(digits)) if cyrnum.drawdots then local sym = cyrnum.dotsymbol result = sym .. result .. sym end end dbg(result) return result end local do_tocyrillic do_tocyrillic = function (n, result) if n < 1000 then local mod100 = n % 100 if #result == 0 and mod100 > 10 and mod100 < 20 then result[#result+1] = "і" result[#result+1] = cyrillic_numerals[1][mod100%10] or false else result[#result+1] = cyrillic_numerals[1][mathfloor(n%10)] or false result[#result+1] = cyrillic_numerals[2][mathfloor((n%100)/10)] or false end result[#result+1] = cyrillic_numerals[3][mathfloor((n%1000)/100)] or false else result = do_tocyrillic(n%1000, result) result = do_tocyrillic(mathfloor(n/1000), result) end return result end local tocyrillic = function (n) local chars = do_tocyrillic(n, { }) return concat_cyrillic_nums(chars) end local Tocyrillic = function (n) local chars = do_tocyrillic(n, { }) return concat_cyrillic_nums(chars, true) end converters.tocyrillic = tocyrillic converters.cyrillicnumerals = tocyrillic converters.Cyrillicnumerals = Tocyrillic function commands.cyrillicnumerals (n) context(tocyrillic(n)) end function commands.Cyrillicnumerals (n) context(Tocyrillic(n)) end