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 | 858 |
1 files changed, 561 insertions, 297 deletions
diff --git a/Master/texmf-dist/tex/context/base/core-con.lua b/Master/texmf-dist/tex/context/base/core-con.lua index dca1c7d10cc..e8ef52d4bf8 100644 --- a/Master/texmf-dist/tex/context/base/core-con.lua +++ b/Master/texmf-dist/tex/context/base/core-con.lua @@ -17,25 +17,34 @@ slower but look nicer this way.</p> local utf = unicode.utf8 local floor, date, time, concat = math.floor, os.date, os.time, table.concat -local lower, format, rep = string.lower, string.format, string.rep -local texsprint, utfchar = tex.sprint, utf.char +local lower, format, rep, match = string.lower, string.format, string.rep, string.match +local utfchar, utfbyte = utf.char, utf.byte local tonumber, tostring = tonumber, tostring -local ctxcatcodes = tex.ctxcatcodes +local settings_to_array = utilities.parsers.settings_to_array +local allocate = utilities.storage.allocate -converters = converters or { } -languages = languages or { } +local context = context ---~ ['arabic-digits'] = { ---~ 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, ---~ 0x0665, 0x0666, 0x0667, 0x0668, 0x0669 ---~ }, ---~ ['persian-digits'] = { ---~ 0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4, ---~ 0x06F5, 0x06F6, 0x06F7, 0x06F8, 0x06F9 ---~ }, +local variables = interfaces.variables -languages.counters = { +converters = converters or { } +local converters = converters + +languages = languages or { } +local languages = languages + +local function number(n) + return tonumber(n) +end + +converters.number = number + +function commands.number(n) context(n) end + +-- to be reconsidered ... languages namespace here, might become local plus a register command + +local counters = allocate { ['**'] = { 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, @@ -111,132 +120,173 @@ languages.counters = { }, } -local counters = languages.counters +languages.counters = counters -counters['ar'] = counters['arabic'] -counters['gr'] = counters['greek'] -counters['g'] = counters['greek'] -counters['sl'] = counters['slovenian'] -counters['kr'] = counters['korean'] -counters['kr-p'] = counters['korean-parent'] -counters['kr-c'] = counters['korean-circle'] +counters['ar'] = counters['arabic'] +counters['gr'] = counters['greek'] +counters['g'] = counters['greek'] +counters['sl'] = counters['slovenian'] +counters['kr'] = counters['korean'] +counters['kr-p'] = counters['korean-parent'] +counters['kr-c'] = counters['korean-circle'] local fallback = utf.byte('0') local function chr(n,m) - if n > 0 and n < 27 then - texsprint(utfchar(n+m)) - end + return (n > 0 and n < 27 and utfchar(n+m)) or "" end -local function chrs(n,m) + +local function chrs(n,m,t) + if not t then + t = { } + end if n > 26 then - chrs(floor((n-1)/26),m) + chrs(floor((n-1)/26),m,t) n = (n-1)%26 + 1 end - texsprint(utfchar(n+m)) + if n ~= 0 then + t[#t+1] = utfchar(n+m) + end + if n <= 26 then + return concat(t) + end end -local function maxchrs(n,m,cmd) + +local function maxchrs(n,m,cmd,t) + if not t then + t = { } + end if n > m then maxchrs(floor((n-1)/m),m,cmd) n = (n-1)%m + 1 end - texsprint(ctxcatcodes, format("%s{%s}",cmd,n)) + t[#t+1] = format("%s{%s}",cmd,n) + if n <= m then + return concat(t) + end end converters.chr = chr converters.chrs = chrs converters.maxchrs = maxchrs ---~ more efficient but needs testing ---~ ---~ local escapes = utffilters.private.escapes ---~ ---~ local function do_alphabetic(n,mapping,chr) ---~ local max = #mapping ---~ if n > max then ---~ do_alphabetic(floor((n-1)/max),max,chr) ---~ n = (n-1)%max+1 ---~ end ---~ n = chr(n,mapping) ---~ texsprint(ctxcatcodes,escapes[n] or utfchar(n)) ---~ end - ---~ local lccodes, uccodes = characters.lccode, characters.uccode - ---~ 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)) ---~ 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 ---~ end ---~ ---~ function converters.Alphabetic(n,code) ---~ do_alphabetic(n,counters[code] or counters['**'],uppercased) ---~ end +local lowercharacter = characters.lcchars +local uppercharacter = characters.ucchars --- - -local function do_alphabetic(n,mapping,mapper) - local chr = mapper(mapping[n] or fallback) +local function do_alphabetic(n,mapping,mapper,t) + 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) - n = (n-1)%max+1 + do_alphabetic(floor((n-1)/max),mapping,mapper,t) + n = (n-1) % max + 1 + end + t[#t+1] = chr + if n <= max then + return concat(t) end - characters.flush(chr) end -function converters.alphabetic(n,code) - do_alphabetic(n,counters[code] or counters['**'],characters.lccode) +local function alphabetic(n,code) + return do_alphabetic(n,counters[code] or counters['**'],lowercharacter) end -function converters.Alphabetic(n,code) - do_alphabetic(n,counters[code] or counters['**'],characters.uccode) +local function Alphabetic(n,code) + return do_alphabetic(n,counters[code] or counters['**'],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 -function converters.character (n) chr (n,96) end -function converters.Character (n) chr (n,64) end -function converters.characters(n) chrs(n,96) end -function converters.Characters(n) chrs(n,64) end +local days = { + [false] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + [true] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +} -function converters.weekday(day,month,year) - texsprint(date("%w",time{year=year,month=month,day=day})+1) +local function weekday(day,month,year) + return date("%w",time{year=year,month=month,day=day}) + 1 end -function converters.isleapyear(year) +local function isleapyear(year) return (year % 400 == 0) or ((year % 100 ~= 0) and (year % 4 == 0)) end -function converters.leapyear(year) - if converters.isleapyear(year) then texsprint(1) else texsprint(0) end +local function leapyear(year) + return isleapyear(year) and 1 or 0 end -local days = { - [false] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - [true] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -} +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 -function converters.nofdays(year,month) - texsprint(days[converters.isleapyear(year)][month]) +local function textime() + return tonumber(date("%H")) * 60 + tonumber(date("%M")) end -function converters.year () texsprint(date("%Y")) end -function converters.month () texsprint(date("%m")) end -function converters.hour () texsprint(date("%H")) end -function converters.minute () texsprint(date("%M")) end -function converters.second () texsprint(date("%S")) end -function converters.textime() texsprint(tonumber(date("%H"))*60+tonumber(date("%M"))) 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.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.textime() context(textime()) end + +function commands.doifleapyearelse(year) + commands.testcase(leapyear(year)) +end local roman = { { [0] = '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX' }, @@ -248,15 +298,20 @@ local function toroman(n) if n >= 4000 then return toroman(floor(n/1000)) .. " " .. toroman(n%1000) else - return rep("M",floor(n/1000)) .. roman[3][floor((n%1000)/100)] .. - roman[2][floor((n%100)/10)] .. roman[1][floor((n% 10)/1)] + return rep("M",floor(n/1000)) .. roman[3][floor((n%1000)/100)] .. roman[2][floor((n%100)/10)] .. roman[1][floor((n% 10)/1)] end end -function converters.romannumerals(n) return texsprint(lower(toroman(n))) end -function converters.Romannumerals(n) return texsprint( toroman(n) ) end +local Romannumerals = toroman + +local function romannumerals(n) return lower(toroman(n)) end + +converters.toroman = toroman +converters.Romannumerals = toroman +converters.romannumerals = romannumerals -converters.toroman = toroman +function commands.romannumerals(n) context(lower(toroman(n))) end +function commands.Romannumerals(n) context( toroman(n)) end --~ local small = { --~ 0x0627, 0x066E, 0x062D, 0x062F, 0x0647, 0x0648, 0x0631 @@ -287,7 +342,7 @@ local large = { { "غ" }, } -function converters.toabjad(n,what) +local function toabjad(n,what) if n <= 0 or n >= 2000 then return tostring(n) elseif what == 2 and n <= 7 then @@ -304,8 +359,16 @@ function converters.toabjad(n,what) end end -function converters.abjadnumerals (n) return texsprint(converters.toabjad(n,false)) end -function converters.abjadnodotnumerals(n) return texsprint(converters.toabjad(n,true)) 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 commands.abjadnumerals (n) context(toabjad(n,false)) end +function commands.abjadnodotnumerals(n) context(toabjad(n,true )) end local vector = { normal = { @@ -363,128 +426,73 @@ local vector = { } } ---~ function tochinese(n,name) -- normal, caps, all ---~ local result = { } ---~ local vector = vector[name] or vector.normal ---~ while true do ---~ if n == 0 then ---~ break ---~ elseif n >= 100000000 then ---~ local m = floor(n/100000000) ---~ if m > 1 then result[#result+1] = tochinese(m) end ---~ result[#result+1] = vector[100000000] ---~ n = n % 100000000 ---~ elseif n >= 10000000 then ---~ result[#result+1] = tochinese(floor(n/10000)) ---~ result[#result+1] = vector[10000] ---~ n = n % 10000 ---~ elseif n >= 1000000 then ---~ result[#result+1] = tochinese(floor(n/10000)) ---~ result[#result+1] = vector[10000] ---~ n = n % 10000 ---~ elseif n >= 100000 then ---~ result[#result+1] = tochinese(floor(n/10000)) ---~ result[#result+1] = vector[10000] ---~ n = n % 10000 ---~ elseif n >= 10000 then ---~ local m = floor(n/10000) ---~ if m > 1 then result[#result+1] = vector[m] end ---~ result[#result+1] = vector[10000] ---~ n = n % 10000 ---~ elseif n >= 1000 then ---~ local m = floor(n/1000) ---~ if m > 1 then result[#result+1] = vector[m] end ---~ result[#result+1] = vector[1000] ---~ n = n % 1000 ---~ elseif n >= 100 then ---~ local m = floor(n/100) ---~ if m > 1 then result[#result+1] = vector[m] end ---~ result[#result+1] = vector[100] ---~ n = n % 100 ---~ elseif n >= 10 then ---~ local m = floor(n/10) ---~ if vector[m*10] then ---~ result[#result+1] = vector[m*10] ---~ else ---~ result[#result+1] = vector[m] ---~ result[#result+1] = vector[10] ---~ end ---~ n = n % 10 ---~ else ---~ result[#result+1] = vector[n] ---~ break ---~ end ---~ end ---~ return concat(result) ---~ end - -function tochinese(n,name) -- normal, caps, all +local function tochinese(n,name) -- normal, caps, all -- improved version by Li Yanrui - local result = { } + local result, r = { }, 0 local vector = vector[name] or vector.normal while true do if n == 0 then break elseif n >= 100000000 then local m = floor(n/100000000) - result[#result+1] = tochinese(m,name) - result[#result+1] = vector[100000000] + r = r + 1 ; result[r] = tochinese(m,name) + r = r + 1 ; result[r] = vector[100000000] local z = n - m * 100000000 - if z > 0 and z < 10000000 then result[#result+1] = vector[0] end + if z > 0 and z < 10000000 then r = r + 1 ; result[r] = vector[0] end n = n % 100000000 elseif n >= 10000000 then local m = floor(n/10000) - result[#result+1] = tochinese(m,name) - result[#result+1] = vector[10000] + r = r + 1 ; result[r] = tochinese(m,name) + r = r + 1 ; result[r] = vector[10000] local z = n - m * 10000 - if z > 0 and z < 1000 then result[#result+1] = vector[0] end + if z > 0 and z < 1000 then r = r + 1 ; result[r] = vector[0] end n = n % 10000 elseif n >= 1000000 then local m = floor(n/10000) - result[#result+1] = tochinese(m,name) - result[#result+1] = vector[10000] + r = r + 1 ; result[r] = tochinese(m,name) + r = r + 1 ; result[r] = vector[10000] local z = n - m * 10000 - if z > 0 and z < 1000 then result[#result+1] = vector[0] end + if z > 0 and z < 1000 then r = r + 1 ; result[r] = vector[0] end n = n % 10000 elseif n >= 100000 then local m = floor(n/10000) - result[#result+1] = tochinese(m,name) - result[#result+1] = vector[10000] + r = r + 1 ; result[r] = tochinese(m,name) + r = r + 1 ; result[r] = vector[10000] local z = n - m * 10000 - if z > 0 and z < 1000 then result[#result+1] = vector[0] end + if z > 0 and z < 1000 then r = r + 1 ; result[r] = vector[0] end n = n % 10000 elseif n >= 10000 then local m = floor(n/10000) - result[#result+1] = vector[m] - result[#result+1] = vector[10000] + r = r + 1 ; result[r] = vector[m] + r = r + 1 ; result[r] = vector[10000] local z = n - m * 10000 - if z > 0 and z < 1000 then result[#result+1] = vector[0] end + if z > 0 and z < 1000 then r = r + 1 ; result[r] = vector[0] end n = n % 10000 elseif n >= 1000 then local m = floor(n/1000) - result[#result+1] = vector[m] - result[#result+1] = vector[1000] + r = r + 1 ; result[r] = vector[m] + r = r + 1 ; result[r] = vector[1000] local z = n - m * 1000 - if z > 0 and z < 100 then result[#result+1] = vector[0] end + if z > 0 and z < 100 then r = r + 1 ; result[r] = vector[0] end n = n % 1000 elseif n >= 100 then local m = floor(n/100) - result[#result+1] = vector[m] - result[#result+1] = vector[100] + r = r + 1 ; result[r] = vector[m] + r = r + 1 ; result[r] = vector[100] local z = n - m * 100 - if z > 0 and z < 10 then result[#result+1] = vector[0] end + if z > 0 and z < 10 then r = r + 1 ; result[r] = vector[0] end n = n % 100 elseif n >= 10 then local m = floor(n/10) if m > 1 and vector[m*10] then - result[#result+1] = vector[m*10] + r = r + 1 ; result[r] = vector[m*10] else - result[#result+1] = vector[m] - result[#result+1] = vector[10] + r = r + 1 ; result[r] = vector[m] + r = r + 1 ; result[r] = vector[10] end n = n % 10 else - result[#result+1] = vector[n] + r = r + 1 ; result[r] = vector[n] break end end @@ -494,112 +502,368 @@ function tochinese(n,name) -- normal, caps, all return concat(result) end ---~ local t = { 1,10,15,25,35,45,11,100,111,1111,10000,11111,100000,111111,1111111,11111111,111111111,100000000,1111111111,11111111111,111111111111,1111111111111 } ---~ for k=1,#t do ---~ local v = t[k] ---~ print(v,tochinese(v),tochinese(v,"all"),tochinese(v,"cap")) ---~ end - -function converters.chinesenumerals (n) return texsprint(tochinese(n,"normal")) end -function converters.chinesecapnumerals(n) return texsprint(tochinese(n,"cap" )) end -function converters.chineseallnumerals(n) return texsprint(tochinese(n,"all" )) end - ---~ Well, since the one asking for this didn't test it the following code is not ---~ enabled. ---~ ---~ -- This Lua version is based on a Javascript by Behdad Esfahbod which in turn ---~ -- is based on GPL'd code by Roozbeh Pournader of the The FarsiWeb Project ---~ -- Group: http://www.farsiweb.info/jalali/jalali.js. ---~ -- ---~ -- We start tables at one, I kept it zero based in order to stay close to ---~ -- the original. ---~ -- ---~ -- Conversion by Hans Hagen ---~ ---~ local g_days_in_month = { [0]=31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } ---~ local j_days_in_month = { [0]=31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 } ---~ ---~ local function div(a,b) ---~ return math.floor(a/b) ---~ end ---~ ---~ local function remainder(a,b) ---~ return a - div(a,b)*b ---~ end ---~ ---~ function gregorian_to_jalali(gy,gm,gd) ---~ local jy, jm, jd, g_day_no, j_day_no, j_np, i ---~ gy, gm, gd = gy - 1600, gm - 1, gd - 1 ---~ g_day_no = 365*gy + div((gy+3),4) - div((gy+99),100) + div((gy+399),400) ---~ i = 0 ---~ while i < gm do ---~ g_day_no = g_day_no + g_days_in_month[i] ---~ i = i + 1 ---~ end ---~ if (gm>1 and ((gy%4==0 and gy%100~=0) or (gy%400==0))) then ---~ g_day_no = g_day_no + 1 ---~ end ---~ g_day_no = g_day_no + gd ---~ j_day_no = g_day_no - 79 ---~ j_np = div(j_day_no,12053) ---~ j_day_no = remainder(j_day_no,12053) ---~ jy = 979 + 33*j_np + 4*div(j_day_no,1461) ---~ j_day_no = remainder(j_day_no,1461) ---~ if j_day_no >= 366 then ---~ jy = jy + div((j_day_no-1),365) ---~ j_day_no = remainder((j_day_no-1),365) ---~ end ---~ i = 0 ---~ while i < 11 and j_day_no >= j_days_in_month[i] do ---~ j_day_no = j_day_no - j_days_in_month[i] ---~ i = i + 1 ---~ end ---~ jm = i + 1 ---~ jd = j_day_no + 1 ---~ return jy, jm, jd ---~ end ---~ ---~ function jalali_to_gregorian(jy,jm,jd) ---~ local gy, gm, gd, g_day_no, j_day_no, leap, i ---~ jy, jm, jd = jy - 979, jm - 1, jd - 1 ---~ j_day_no = 365*jy + div(jy,33)*8 + div((remainder(jy,33)+3),4) ---~ i = 0 ---~ while i < jm do ---~ j_day_no = j_day_no + j_days_in_month[i] ---~ i = i + 1 ---~ end ---~ j_day_no = j_day_no + jd ---~ g_day_no = j_day_no + 79 ---~ gy = 1600 + 400*div(g_day_no,146097) ---~ g_day_no = remainder (g_day_no, 146097) ---~ leap = 1 ---~ if g_day_no >= 36525 then ---~ g_day_no = g_day_no - 1 ---~ gy = gy + 100*div(g_day_no,36524) ---~ g_day_no = remainder (g_day_no, 36524) ---~ if g_day_no >= 365 then ---~ g_day_no = g_day_no + 1 ---~ else ---~ leap = 0 ---~ end ---~ end ---~ gy = gy + 4*div(g_day_no,1461) ---~ g_day_no = remainder (g_day_no, 1461) ---~ if g_day_no >= 366 then ---~ leap = 0 ---~ g_day_no = g_day_no - 1 ---~ gy = gy + div(g_day_no, 365) ---~ g_day_no = remainder(g_day_no, 365) ---~ end ---~ i = 0 ---~ while g_day_no >= g_days_in_month[i] + ((i == 1 and leap) or 0) do ---~ g_day_no = g_day_no - g_days_in_month[i] + ((i == 1 and leap) or 0) ---~ i = i + 1 ---~ end ---~ gm = i + 1 ---~ gd = g_day_no + 1 ---~ return gy, gm, gd ---~ end ---~ ---~ print(gregorian_to_jalali(2009,02,24)) ---~ print(jalali_to_gregorian(1387,12,06)) +-- local t = { 1,10,15,25,35,45,11,100,111,1111,10000,11111,100000,111111,1111111,11111111,111111111,100000000,1111111111,11111111111,111111111111,1111111111111 } +-- for k=1,#t do +-- local v = t[k] +-- print(v,tochinese(v),tochinese(v,"all"),tochinese(v,"cap")) +-- 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 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 { } + +storage.register("converters/sequences", converters.sequences, "converters.sequences") + +local sequences = converters.sequences + +function converters.define(name,set) + sequences[name] = settings_to_array(set) +end + +commands.defineconversion = converters.define + +local function convert(method,n) -- todo: language + local converter = converters[method] + if converter then + return converter(n) + else + local lowermethod = lower(method) + local linguistic = counters[lowermethod] + if linguistic then + return do_alphabetic(n,linguistic,lowermethod == method and lowercharacter or uppercharacter) + end + local sequence = sequences[method] + if sequence then + local max = #sequence + if n > max then + return sequence[(n-1) % max + 1] + else + return sequence[n] + end + else + return n + end + end +end + +converters.convert = convert + +function commands.checkedconversion(method,n) + context(convert(method,n)) +end + +-- Well, since the one asking for this didn't test it the following code is not +-- enabled. +-- +-- -- This Lua version is based on a Javascript by Behdad Esfahbod which in turn +-- -- is based on GPL'd code by Roozbeh Pournader of the The FarsiWeb Project +-- -- Group: http://www.farsiweb.info/jalali/jalali.js. +-- -- +-- -- We start tables at one, I kept it zero based in order to stay close to +-- -- the original. +-- -- +-- -- Conversion by Hans Hagen +-- +-- local g_days_in_month = { [0]=31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +-- local j_days_in_month = { [0]=31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 } +-- +-- local function div(a,b) +-- return math.floor(a/b) +-- end +-- +-- local function remainder(a,b) +-- return a - div(a,b)*b +-- end +-- +-- function gregorian_to_jalali(gy,gm,gd) +-- local jy, jm, jd, g_day_no, j_day_no, j_np, i +-- gy, gm, gd = gy - 1600, gm - 1, gd - 1 +-- g_day_no = 365*gy + div((gy+3),4) - div((gy+99),100) + div((gy+399),400) +-- i = 0 +-- while i < gm do +-- g_day_no = g_day_no + g_days_in_month[i] +-- i = i + 1 +-- end +-- if (gm>1 and ((gy%4==0 and gy%100~=0) or (gy%400==0))) then +-- g_day_no = g_day_no + 1 +-- end +-- g_day_no = g_day_no + gd +-- j_day_no = g_day_no - 79 +-- j_np = div(j_day_no,12053) +-- j_day_no = remainder(j_day_no,12053) +-- jy = 979 + 33*j_np + 4*div(j_day_no,1461) +-- j_day_no = remainder(j_day_no,1461) +-- if j_day_no >= 366 then +-- jy = jy + div((j_day_no-1),365) +-- j_day_no = remainder((j_day_no-1),365) +-- end +-- i = 0 +-- while i < 11 and j_day_no >= j_days_in_month[i] do +-- j_day_no = j_day_no - j_days_in_month[i] +-- i = i + 1 +-- end +-- jm = i + 1 +-- jd = j_day_no + 1 +-- return jy, jm, jd +-- end +-- +-- function jalali_to_gregorian(jy,jm,jd) +-- local gy, gm, gd, g_day_no, j_day_no, leap, i +-- jy, jm, jd = jy - 979, jm - 1, jd - 1 +-- j_day_no = 365*jy + div(jy,33)*8 + div((remainder(jy,33)+3),4) +-- i = 0 +-- while i < jm do +-- j_day_no = j_day_no + j_days_in_month[i] +-- i = i + 1 +-- end +-- j_day_no = j_day_no + jd +-- g_day_no = j_day_no + 79 +-- gy = 1600 + 400*div(g_day_no,146097) +-- g_day_no = remainder (g_day_no, 146097) +-- leap = 1 +-- if g_day_no >= 36525 then +-- g_day_no = g_day_no - 1 +-- gy = gy + 100*div(g_day_no,36524) +-- g_day_no = remainder (g_day_no, 36524) +-- if g_day_no >= 365 then +-- g_day_no = g_day_no + 1 +-- else +-- leap = 0 +-- end +-- end +-- gy = gy + 4*div(g_day_no,1461) +-- g_day_no = remainder (g_day_no, 1461) +-- if g_day_no >= 366 then +-- leap = 0 +-- g_day_no = g_day_no - 1 +-- gy = gy + div(g_day_no, 365) +-- g_day_no = remainder(g_day_no, 365) +-- end +-- i = 0 +-- while g_day_no >= g_days_in_month[i] + ((i == 1 and leap) or 0) do +-- g_day_no = g_day_no - g_days_in_month[i] + ((i == 1 and leap) or 0) +-- i = i + 1 +-- end +-- gm = i + 1 +-- gd = g_day_no + 1 +-- return gy, gm, gd +-- 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 +-- +-- local function do_alphabetic(n,mapping,chr) +-- local max = #mapping +-- if n > max then +-- do_alphabetic(floor((n-1)/max),max,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 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)) +-- 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 +-- end +-- +-- function converters.Alphabetic(n,code) +-- do_alphabetic(n,counters[code] or counters['**'],uppercased) +-- end + +-- -- + +local ordinals = { + english = function(n) + local two = n % 100 + if two == 11 or two == 12 or to == 13 then + return "th" + else + local one = n % 10 + if one == 1 then + return "st" + elseif one == 2 then + return "nd" + elseif one == 3 then + return "rd" + else + return "th" + end + end + end, + dutch = function(n) + return "e" + end, + french = function(n) + if n == 1 then + return "er" + end + end, +} + +ordinals.en = ordinals.english +ordinals.nl = ordinals.dutch +ordinals.fr = ordinals.french + +function converters.ordinal(n,language) + local t = language and ordinals[language] + return t and t(n) +end + +function commands.ordinal(n,language) + local t = language and ordinals[language] + local o = t and t(n) + if o then + context.highordinalstr(o) + end +end + +-- -- + +local v_day = variables.day +local v_year = variables.year +local v_month = variables.month +local v_weekday = variables.weekday +local v_referral = variables.referral +local v_space = variables.space + +local convert = converters.convert + +local days = { + variables.sunday, + variables.monday, + variables.tuesday, + variables.wednesday, + variables.thursday, + variables.friday, + variables.saturday, +} + +local months = { + variables.january, + variables.february, + variables.march, + variables.april, + variables.may, + variables.june, + variables.july, + variables.august, + variables.september, + variables.october, + variables.november, + variables.december, +} + +function commands.dayname(n) + context.labeltext(days[n] or "unknown") +end + +function commands.weekdayname(day,month,year) + context.labeltext(days[weekday(day,month,year)] or "unknown") +end + +function commands.monthname(n) + context.labeltext(months[n] or "unknown") +end + +function commands.monthmnem(n) + local m = months[n] + context.labeltext(m and (m ..":mnem") or "unknown") +end + +-- a prelude to a function that we can use at the lua end + +-- historic : day+ month:mnem +-- maybe better: day:ord month:mmem + +function commands.currentdate(str,currentlanguage) -- j and jj obsolete + local list = utilities.parsers.settings_to_array(str) + 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 = match(entry,"^([^%+:]+)(.*)$") + local ordinal, mnemonic, whatordinal = false, false, nil + if not tag then + tag = entry + elseif plus == "+" or plus == "ord" then + ordinal = true + elseif plus == "mnem" then + mnemonic = true + end + if not auto and (tag == v_year or tag == v_month or tag == v_day or tag == v_weekday) then + context.space() + end + auto = false + if tag == v_year or tag == "y" then + context(year) + elseif tag == "yy" then + context("%02i",year % 100) + elseif tag == "Y" then + context(year) + elseif tag == v_month or tag == "m" then + if mnemonic then + commands.monthmnem(month) + else + commands.monthname(month) + end + elseif tag == "mm" then + context("%02i",month) + elseif tag == "M" then + context(month) + elseif tag == v_day or tag == "d" then + context.convertnumber(v_day,day) + whatordinal = day + elseif tag == "dd" then + context("%02i",day) + whatordinal = day + elseif tag == "D" then + context(day) + whatordinal = day + elseif tag == v_weekday or tag == "w" then + commands.dayname(weekday(day,month,year)) + elseif tag == "W" then + context(weekday(day,month,year)) + elseif tag == v_referral then + context("%04i%02i%02i",year,month,day) + elseif tag == v_space or tag == "\\ " then + context.space() + auto = true + elseif tag ~= "" then + context(tag) + auto = true + end + if ordinal and whatordinal then + commands.ordinal(whatordinal,currentlanguage) + end + end +end |