#!/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 cyrnum.last_synonyms = { final = true, last = true, right = true, rightmost = true, ["false"] = true, } cyrnum.yes_synonyms = { yes = true, yeah = true, ["true"] = true, } 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 == "l" then local result = lreverse(list) result[#result+1] = cyrillic_titlo return result end -- “middle” (“m”) or whatever local pos = mathceil(tablemaxn(list)/2) tableinsert(list, mathceil(tablemaxn(list)/2), cyrillic_titlo) return lreverse(list) end, mp = function (list) local result = { } local titlospan = cyrnum.titlospan local titlostart = titlospan and #list > titlospan and #list-titlospan or 1 for i=tablemaxn(list), 1, -1 do if i == titlostart then result[#result+1] = start_titlo end 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 -- vim:ft=lua:ts=2:sw=2:expandtab:fo=croql