diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/core-con.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/core-con.lua | 469 |
1 files changed, 340 insertions, 129 deletions
diff --git a/Master/texmf-dist/tex/context/base/core-con.lua b/Master/texmf-dist/tex/context/base/core-con.lua index e4b516e3b43..cb284b9a781 100644 --- a/Master/texmf-dist/tex/context/base/core-con.lua +++ b/Master/texmf-dist/tex/context/base/core-con.lua @@ -14,38 +14,37 @@ slower but look nicer this way.</p> <p>Some code may move to a module in the language namespace.</p> --ldx]]-- -local utf = unicode.utf8 +local command, context = commands, context local floor, date, time, concat = math.floor, os.date, os.time, table.concat -local lower, format, rep, match = string.lower, string.format, string.rep, string.match +local lower, rep, match = string.lower, string.rep, string.match local utfchar, utfbyte = utf.char, utf.byte local tonumber, tostring = tonumber, tostring -local settings_to_array = utilities.parsers.settings_to_array -local allocate = utilities.storage.allocate +local context = context -local context = context +local settings_to_array = utilities.parsers.settings_to_array +local allocate = utilities.storage.allocate +local formatters = string.formatters +local variables = interfaces.variables -local variables = interfaces.variables +converters = converters or { } +local converters = converters -converters = converters or { } -local converters = converters +languages = languages or { } +local languages = languages -languages = languages or { } -local languages = languages - -local function number(n) - return tonumber(n) -end - -converters.number = number +converters.number = tonumber +converters.numbers = tonumber function commands.number(n) context(n) end +commands.numbers = commands.number + -- to be reconsidered ... languages namespace here, might become local plus a register command local counters = allocate { - ['**'] = { + ['default'] = { -- no metatable as we do a test on keys 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, @@ -135,7 +134,7 @@ counters['kr'] = counters['korean'] counters['kr-p'] = counters['korean-parent'] counters['kr-c'] = counters['korean-circle'] -local fallback = utf.byte('0') +local fallback = utfbyte('0') local function chr(n,m) return (n > 0 and n < 27 and utfchar(n+m)) or "" @@ -165,7 +164,7 @@ local function maxchrs(n,m,cmd,t) maxchrs(floor((n-1)/m),m,cmd) n = (n-1)%m + 1 end - t[#t+1] = format("%s{%s}",cmd,n) + t[#t+1] = formatters["%s{%s}"](cmd,n) if n <= m then return concat(t) end @@ -178,51 +177,44 @@ converters.maxchrs = maxchrs local lowercharacter = characters.lcchars local uppercharacter = characters.ucchars -local function do_alphabetic(n,mapping,mapper,t) +local function do_alphabetic(n,mapping,mapper,t) -- todo: make zero based variant (initial n + 1) if not t then t = { } end - local chr = mapping[n] or fallback - if mapper then - chr = mapper[chr] - end local max = #mapping if n > max then do_alphabetic(floor((n-1)/max),mapping,mapper,t) n = (n-1) % max + 1 end - t[#t+1] = chr + local chr = mapping[n] or fallback + t[#t+1] = mapper and mapper[chr] or chr if n <= max then return concat(t) end end -local function alphabetic(n,code) - return do_alphabetic(n,counters[code] or counters['**'],lowercharacter) +function converters.alphabetic(n,code) + return do_alphabetic(n,counters[code] or counters.default,lowercharacter) end -local function Alphabetic(n,code) - return do_alphabetic(n,counters[code] or counters['**'],uppercharacter) +function converters.Alphabetic(n,code) + return do_alphabetic(n,counters[code] or counters.default,uppercharacter) end -local function character (n) return chr (n,96) end -local function Character (n) return chr (n,64) end -local function characters(n) return chrs(n,96) end -local function Characters(n) return chrs(n,64) end - -converters.alphabetic = alphabetic -converters.Alphabetic = Alphabetic -converters.character = character -converters.Character = Character -converters.characters = characters -converters.Characters = Characters - -function commands.alphabetic(n,c) context(alphabetic(n,c)) end -function commands.Alphabetic(n,c) context(Alphabetic(n,c)) end -function commands.character (n) context(character (n)) end -function commands.Character (n) context(Character (n)) end -function commands.characters(n) context(characters(n)) end -function commands.Characters(n) context(Characters(n)) end +local lower_offset = 96 +local upper_offset = 64 + +function converters.character (n) return chr (n,lower_offset) end +function converters.Character (n) return chr (n,upper_offset) end +function converters.characters(n) return chrs(n,lower_offset) end +function converters.Characters(n) return chrs(n,upper_offset) end + +function commands.alphabetic(n,c) context(do_alphabetic(n,counters[c],lowercharacter)) end +function commands.Alphabetic(n,c) context(do_alphabetic(n,counters[c],uppercharacter)) end +function commands.character (n) context(chr (n,lower_offset)) end +function commands.Character (n) context(chr (n,upper_offset)) end +function commands.characters(n) context(chrs(n,lower_offset)) end +function commands.Characters(n) context(chrs(n,upper_offset)) end local days = { [false] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, @@ -245,52 +237,35 @@ local function nofdays(year,month) return days[isleapyear(year)][month] end -local function year () return date("%Y") end -local function month () return date("%m") end -local function hour () return date("%H") end -local function minute() return date("%M") end -local function second() return date("%S") end - local function textime() return tonumber(date("%H")) * 60 + tonumber(date("%M")) end +function converters.year () return date("%Y") end +function converters.month () return date("%m") end +function converters.hour () return date("%H") end +function converters.minute() return date("%M") end +function converters.second() return date("%S") end + converters.weekday = weekday converters.isleapyear = isleapyear converters.leapyear = leapyear converters.nofdays = nofdays -converters.year = year -converters.month = month -converters.hour = hour -converters.minute = minute -converters.second = second converters.textime = textime -function commands.weekday(day,month,year) - context(weekday(day,month,year)) -end - -function commands.isleapyear(year) - context(isleapyear(year)) -end - -function commands.leapyear(year) - context(leapyear(year)) -end - -function commands.nofdays(year,month) - context(nofdays(year,month)) -end +function commands.weekday (day,month,year) context(weekday (day,month,year)) end +function commands.leapyear(year) context(leapyear(year)) end -- rather useless +function commands.nofdays (year,month) context(nofdays (year,month)) end -function commands.year () context(year ()) end -function commands.month () context(month ()) end -function commands.hour () context(hour ()) end -function commands.minute () context(minute ()) end -function commands.second () context(second ()) end +function commands.year () context(date("%Y")) end +function commands.month () context(date("%m")) end +function commands.hour () context(date("%H")) end +function commands.minute () context(date("%M")) end +function commands.second () context(date("%S")) end function commands.textime() context(textime()) end function commands.doifleapyearelse(year) - commands.testcase(leapyear(year)) + commands.doifelse(isleapyear(year)) end local roman = { @@ -307,13 +282,9 @@ local function toroman(n) end end -local Romannumerals = toroman - -local function romannumerals(n) return lower(toroman(n)) end - converters.toroman = toroman converters.Romannumerals = toroman -converters.romannumerals = romannumerals +converters.romannumerals = function(n) return lower(toroman(n)) end function commands.romannumerals(n) context(lower(toroman(n))) end function commands.Romannumerals(n) context( toroman(n)) end @@ -366,11 +337,8 @@ end converters.toabjad = toabjad -local function abjadnumerals (n) return toabjad(n,false) end -local function abjadnodotnumerals(n) return toabjad(n,true ) end - -converters.abjadnumerals = abjadnumerals -converters.abjadnodotnumerals = abjadnodotnumerals +function converters.abjadnumerals (n) return toabjad(n,false) end +function converters.abjadnodotnumerals(n) return toabjad(n,true ) end function commands.abjadnumerals (n) context(toabjad(n,false)) end function commands.abjadnodotnumerals(n) context(toabjad(n,true )) end @@ -515,23 +483,18 @@ end converters.tochinese = tochinese -local function chinesenumerals (n) return tochinese(n,"normal") end -local function chinesecapnumerals(n) return tochinese(n,"cap" ) end -local function chineseallnumerals(n) return tochinese(n,"all" ) end - -converters.chinesenumerals = chinesenumerals -converters.chinesecapnumerals = chinesecapnumerals -converters.chineseallnumerals = chineseallnumerals +function converters.chinesenumerals (n) return tochinese(n,"normal") end +function converters.chinesecapnumerals(n) return tochinese(n,"cap" ) end +function converters.chineseallnumerals(n) return tochinese(n,"all" ) end function commands.chinesenumerals (n) context(tochinese(n,"normal")) end function commands.chinesecapnumerals(n) context(tochinese(n,"cap" )) end function commands.chineseallnumerals(n) context(tochinese(n,"all" )) end converters.sequences = converters.sequences or { } +local sequences = converters.sequences -storage.register("converters/sequences", converters.sequences, "converters.sequences") - -local sequences = converters.sequences +storage.register("converters/sequences", sequences, "converters.sequences") function converters.define(name,set) sequences[name] = settings_to_array(set) @@ -669,44 +632,42 @@ end -- print(gregorian_to_jalali(2009,02,24)) -- print(jalali_to_gregorian(1387,12,06)) --- more efficient but needs testing --- --- local escapes = utffilters.private.escapes --- +-- -- more efficient but needs testing + +-- local escapes = characters.filters.utf.private.escapes + -- local function do_alphabetic(n,mapping,chr) -- local max = #mapping -- if n > max then --- do_alphabetic(floor((n-1)/max),max,chr) +-- do_alphabetic(floor((n-1)/max),mapping,chr) -- n = (n-1)%max+1 -- end -- n = chr(n,mapping) -- context(escapes[n] or utfchar(n)) -- end --- --- local lccodes, uccodes = characters.lccode, characters.uccode --- + +-- local lccodes, uccodes, safechar = characters.lccode, characters.uccode, commands.safechar + -- local function do_alphabetic(n,mapping,chr) -- local max = #mapping -- if n > max then -- do_alphabetic(floor((n-1)/max),mapping,chr) -- n = (n-1)%max+1 -- end --- characters.flush(chr(n,mapping)) +-- safechar(chr(n,mapping)) -- end --- + -- local function lowercased(n,mapping) return characters.lccode(mapping[n] or fallback) end -- local function uppercased(n,mapping) return characters.uccode(mapping[n] or fallback) end --- + -- function converters.alphabetic(n,code) --- do_alphabetic(n,counters[code] or counters['**'],lowercased) -- lccode catches wrong tables +-- do_alphabetic(n,counters[code] or counters.default,lowercased) -- lccode catches wrong tables -- end --- + -- function converters.Alphabetic(n,code) --- do_alphabetic(n,counters[code] or counters['**'],uppercased) +-- do_alphabetic(n,counters[code] or counters.default,uppercased) -- end --- -- - local ordinals = { english = function(n) local two = n % 100 @@ -753,6 +714,255 @@ function commands.ordinal(n,language) end end +-- verbose numbers + +-- verbose numbers + +local data = allocate() +local verbose = { data = data } +converters.verbose = verbose + +-- verbose english + +local words = { + [0] = "zero", + [1] = "one", + [2] = "two", + [3] = "three", + [4] = "four", + [5] = "five", + [6] = "six", + [7] = "seven", + [8] = "eight", + [9] = "nine", + [10] = "ten", + [11] = "eleven", + [12] = "twelve", + [13] = "thirteen", + [14] = "fourteen", + [15] = "fifteen", + [16] = "sixteen", + [17] = "seventeen", + [18] = "eighteen", + [19] = "nineteen", + [20] = "twenty", + [30] = "thirty", + [40] = "forty", + [50] = "fifty", + [60] = "sixty", + [70] = "seventy", + [80] = "eighty", + [90] = "ninety", + [100] = "hundred", + [1000] = "thousand", + [1000^2] = "million", + [1000^3] = "billion", + [1000^4] = "trillion", +} + +local function translate(n) + local w = words[n] + if w then + return w + end + local t = { } + local function compose_one(n) + local w = words[n] + if w then + t[#t+1] = w + return + end + local a, b = floor(n/100), n % 100 + if a == 10 then + t[#t+1] = words[1] + t[#t+1] = words[1000] + elseif a > 0 then + t[#t+1] = words[a] + t[#t+1] = words[100] + -- don't say 'nine hundred zero' + if b == 0 then + return + end + end + if words[b] then + t[#t+1] = words[b] + else + a, b = floor(b/10), n % 10 + t[#t+1] = words[a*10] + t[#t+1] = words[b] + end + end + local function compose_two(n,m) + if n > (m-1) then + local a, b = floor(n/m), n % m + if a > 0 then + compose_one(a) + end + t[#t+1] = words[m] + n = b + end + return n + end + n = compose_two(n,1000^4) + n = compose_two(n,1000^3) + n = compose_two(n,1000^2) + n = compose_two(n,1000^1) + if n > 0 then + compose_one(n) + end + return #t > 0 and concat(t," ") or tostring(n) +end + +data.english = { + words = words, + translate = translate, +} + +data.en = data.english + +-- print(translate(11111111)) +-- print(translate(2221101)) +-- print(translate(1111)) +-- print(translate(1218)) +-- print(translate(1234)) +-- print(translate(12345)) +-- print(translate(12345678900000)) + +-- verbose spanish (unchecked) + +local words = { + [1] = "uno", + [2] = "dos", + [3] = "tres", + [4] = "cuatro", + [5] = "cinco", + [6] = "seis", + [7] = "siete", + [8] = "ocho", + [9] = "nueve", + [10] = "diez", + [11] = "once", + [12] = "doce", + [13] = "trece", + [14] = "catorce", + [15] = "quince", + [16] = "dieciséis", + [17] = "diecisiete", + [18] = "dieciocho", + [19] = "diecinueve", + [20] = "veinte", + [21] = "veintiuno", + [22] = "veintidós", + [23] = "veintitrés", + [24] = "veinticuatro", + [25] = "veinticinco", + [26] = "veintiséis", + [27] = "veintisiete", + [28] = "veintiocho", + [29] = "veintinueve", + [30] = "treinta", + [40] = "cuarenta", + [50] = "cincuenta", + [60] = "sesenta", + [70] = "setenta", + [80] = "ochenta", + [90] = "noventa", + [100] = "ciento", + [200] = "doscientos", + [300] = "trescientos", + [400] = "cuatrocientos", + [500] = "quinientos", + [600] = "seiscientos", + [700] = "setecientos", + [800] = "ochocientos", + [900] = "novecientos", + [1000] = "mil", + [1000^2] = "millón", + [1000^3] = "mil millónes", + [1000^4] = "billón", +} + +local function translate(n) + local w = words[n] + if w then + return w + end + local t = { } + local function compose_one(n) + local w = words[n] + if w then + t[#t+1] = w + return + end + -- a, b = hundreds, remainder + local a, b = floor(n/100), n % 100 + -- one thousand + if a == 10 then + t[#t+1] = words[1] + t[#t+1] = words[1000] + -- x hundred (n.b. this will not give thirteen hundred because + -- compose_one(n) is only called after + -- `n = compose(two(n, 1000^1))`. + elseif a > 0 then + t[#t+1] = words[a*100] + end + -- the remainder + if words[b] then + t[#t+1] = words[b] + else + -- a, b = tens, remainder + a, b = floor(b/10), n % 10 + t[#t+1] = words[a*10] + t[#t+1] = "y" + t[#t+1] = words[b] + end + end + -- compose_two handles x billion, ... x thousand. When 1000 or less is + -- left, compose_one takes over. + local function compose_two(n,m) + if n > (m-1) then + local a, b = floor(n/m), n % m + if a > 0 then + compose_one(a) + end + t[#t+1] = words[m] + n = b + end + return n + end + n = compose_two(n,1000^4) + n = compose_two(n,1000^3) + n = compose_two(n,1000^2) + n = compose_two(n,1000^1) + if n > 0 then + compose_one(n) + end + return #t > 0 and concat(t," ") or tostring(n) +end + +data.spanish = { + words = words, + translate = translate, +} + +data.es = data.spanish + +-- print(translate(31)) +-- print(translate(101)) +-- print(translate(199)) + +-- verbose handler: + +function converters.verbose.translate(n,language) + local t = language and data[language] + return t and t.translate(n) or n +end + +function commands.verbose(n,language) + local t = language and data[language] + context(t and t.translate(n) or n) +end + -- -- local v_day = variables.day @@ -775,18 +985,18 @@ local days = { -- not variables.sunday } local months = { -- not variables.januari - "january", - "february", - "march", - "april", - "may", - "june", - "july", - "august", - "september", - "october", - "november", - "december", + "january", + "february", + "march", + "april", + "may", + "june", + "july", + "august", + "september", + "october", + "november", + "december", } function commands.dayname(n) @@ -813,11 +1023,12 @@ end function commands.currentdate(str,currentlanguage) -- second argument false : no label local list = utilities.parsers.settings_to_array(str) + local splitlabel = languages.labels.split or string.itself -- we need to get the loading order right local year, month, day = tex.year, tex.month, tex.day local auto = true for i=1,#list do local entry = list[i] - local tag, plus = languages.labels.split(entry) + local tag, plus = splitlabel(entry) local ordinal, mnemonic, whatordinal = false, false, nil if not tag then tag = entry @@ -883,7 +1094,7 @@ function commands.currentdate(str,currentlanguage) -- second argument false : no if currentlanguage == false then -- ignore else - context("%s",converters.ordinal(whatordinal,currentlanguage)) + context(converters.ordinal(whatordinal,currentlanguage)) -- no "%s" needed end end end |