diff options
| author | Peng Wu <alexepico@gmail.com> | 2010-06-21 13:06:01 +0800 |
|---|---|---|
| committer | Peng Wu <alexepico@gmail.com> | 2010-06-21 13:06:01 +0800 |
| commit | 0f0a0be50b9946429b06357d9f729bbfc358c109 (patch) | |
| tree | 70f333ff6beae399bfa13f1cd0eafec793a8b861 /lua | |
| parent | ac1476aabed3efb8c96f45c3eac225ece5376394 (diff) | |
| download | ibus-libpinyin-0f0a0be50b9946429b06357d9f729bbfc358c109.tar.gz ibus-libpinyin-0f0a0be50b9946429b06357d9f729bbfc358c109.tar.xz ibus-libpinyin-0f0a0be50b9946429b06357d9f729bbfc358c109.zip | |
add base.lua
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/base.lua | 912 |
1 files changed, 912 insertions, 0 deletions
diff --git a/lua/base.lua b/lua/base.lua new file mode 100644 index 0000000..898c65c --- /dev/null +++ b/lua/base.lua @@ -0,0 +1,912 @@ +-- encoding: UTF-8 + +_CHINESE_DIGITS = { + [0] = "〇", + [1] = "一", + [2] = "二", + [3] = "三", + [4] = "四", + [5] = "五", + [6] = "六", + [7] = "七", + [8] = "八", + [9] = "九", + [10] = "十", +} +_DATE_PATTERN = "^(%d+)-(%d+)-(%d+)$" +_TIME_PATTERN = "^(%d+):(%d+)$" + +function GetChineseMathNum(num) + local ret + if num < 10 then + ret = _CHINESE_DIGITS[num] + elseif num < 20 then + ret = _CHINESE_DIGITS[10] + if num > 10 then + ret = ret .. _CHINESE_DIGITS[num % 10] + end + elseif num < 100 then + local mod = num % 10 + ret = _CHINESE_DIGITS[(num - mod) / 10] .. _CHINESE_DIGITS[10] + if mod > 0 then + ret = ret .. _CHINESE_DIGITS[mod] + end + else + error("Invalid number") + end + return ret +end + +function GetChineseNonMathNum(num) + local ret = "" + for ch in tostring(num):gmatch(".") do + if ch >= "0" and ch <= "9" then + ch = _CHINESE_DIGITS[tonumber(ch)] + end + ret = ret .. ch + end + return ret +end + +function _VerifyTime(hour, minute) + if hour < 0 or hour > 23 or minute < 0 or minute > 59 then + error("Invalid time") + end +end + +function _VerifyDate(month, day) + if month < 1 or month > 12 or day < 1 or day > _MONTH_TABLE_LEAF[month] then + error("Invalid date") + end +end + +function _VerifyDateWithYear(year, month, day) + _VerifyDate(month, day) + if year < 1 or year > 9999 then + error("Invalid year") + end + if month == 2 and day == 29 then + if year % 400 ~= 0 and year % 100 == 0 then + error("Invalid lunar day") + end + if year % 4 ~= 0 then + error("Invalid lunar day") + end + end +end + +function GetChineseDate(y, m, d, full) + if full then + return GetChineseNonMathNum(y) .. "年" .. + GetChineseMathNum(m) .. "月" .. + GetChineseMathNum(d) .. "日" + else + return y .. "年" .. m .. "月" .. d .. "日" + end +end + +function GetChineseTime(h, m, full) + if full then + local ret = GetChineseMathNum(h) .. "时" + if m > 0 then + ret = ret .. GetChineseMathNum(m) .. "分" + end + return ret + else + return h .. "时" .. m .. "分" + end +end + +function NormalizeDate(y, m, d) + return string.format("%d-%02d-%02d", y, m, d) +end + +function NormalizeTime(h, m) + return string.format("%02d:%02d", h, m) +end + +function GetTime(input) + local now = input + if #input == 0 then + now = os.date("%H:%M") + end + local hour, minute + now:gsub(_TIME_PATTERN, function(h, m) + hour = tonumber(h) + minute = tonumber(m) + end) + _VerifyTime(hour, minute) + return { + NormalizeTime(hour, minute), + GetChineseTime(hour, minute, false), + GetChineseTime(hour, minute, true), + } +end + +function GetDate(input) + local now = input + if #input == 0 then + now = os.date("%Y-%m-%d") + end + local year, month, day + now:gsub(_DATE_PATTERN, function(y, m, d) + year = tonumber(y) + month = tonumber(m) + day = tonumber(d) + end) + _VerifyDateWithYear(year, month, day) + return { + NormalizeDate(year, month, day), + GetChineseDate(year, month, day, false), + GetChineseDate(year, month, day, true), + } +end + +---------------------------------- + +_MATH_KEYWORDS = { + "abs", "acos", "asin", "atan", "atan2", "ceil", "cos", "cosh", "deg", "exp", + "floor", "fmod", "frexp", "ldexp", "log", "log10", "max", "min", "modf", "pi", + "pow", "rad", "random", "randomseed", "sin", "sinh", "sqrt", "tan", "tanh", +} + +function _AddMathKeyword(input) + local ret = input + for _, keyword in pairs(_MATH_KEYWORDS) do + ret = ret:gsub(string.format("([^%%a\.])(%s\(.-\))", keyword), "%1math\.%2") + ret = ret:gsub(string.format("^(%s\(.-\))", keyword), "math\.%1") + end + return ret +end + +function Compute(input) + local expr = "return " .. _AddMathKeyword(input) + local func = loadstring(expr) + if func == nil then + return "-- 未完整表达式 --" + end + local ret = func() + if ret == math.huge then -- div/0 + return "-- 计算错误 --" + end + if ret ~= ret then + -- We rely on the property that NaN is the only value not equal to itself. + return "-- 计算错误 --" + end + return ret +end + +---------------------------------- + +_TO_BE_REPLACED_FLAG = "#TO_BE_REPLACED#" + +_ASCII_IMAGE_TABLE = { + +["birthday"] = { [[ + +.......................................................................... + + H A P P Y B I R T H D A Y #TO_BE_REPLACED# ! + +.......................................................................... +.....................**............................*...................... +.....................++..............**..........*+.*..................... +...................*+*+..............**..........*++*..................... +.................*+***++*............*+........*.*.*++*................... +.................**..*+*.*..........*+.......*..*+.*.**................... +................+*.**++**+*........*+*+*.....*.*+**+***................... +................+**+*.*+**+*.....*+*.*++*.....**+**++*.................... +.................**++**+*++*....**..*++.*+.....**+..+*.................... +..................*+++.++*......+*.*+***.+.......*.+..**.................. +.............********..*.***...*.**+*.*+**.....+*+..****.................. +............*+*...****...+*....*+++++**++.....********.................... +.............++....***+++**....+.*******....****...*******................ +..............*+*........*+******+***..****.**+.......*+**................ +..............*+*..........+++...***+.#+**...*+*.......+*................. +..............*+*..........+**+*.....**+++*..++.........++................ +..............*+*..........**.*+*........*+*..*+*......*+**............... +..............*+*............+++*..........**.*+*........*++.............. +..............*+*............+++*...........*+*..........*++.............. +...........***+.*............+++*...........*+*..........*+***............ +.......******.*+*............+++*...........*+*..........*+*.++*.......... +......***......++...........*+*+*...........*++*************...**++....... +....*+*.**......***************+*...........*+*********....*.....***...... +....++...*+**.................*+*...........*+*............*....**.**..... +...*+*.....*******.............*+*..........*+*....**********.***...**.... +...*+*...*......************....*************...**..........****......*... +...++....*******.......***+++*********************************.......**... +..++.....++...*+*......*+***+*..........*********..........**...*..*..*... +..+*....*+*...*+......*+....*+*.......*+**.....*+*........**.....*+**++... +....*+.....**+.......**.....**........**........+*........**.......**+*... +...*.+......*+***.*****.....*+......***.........+*........+*.......*+**... +...*.+........******.........*********..........****..*****......***+*.... +....*.*.....................................................**....*+...... +....**+*...................................................+*****+*....... +........**++......................................*++*....*++*............ +........*+******...............................*************.............. +...............****++*###*******###########*****++........................ +.......................................................................... +]], +"生日蛋糕"}, + +["search"] = { [[ + + --\--+--/-- + { o_o } +┏━━━━━━━━━━oOo━(__)━oOo━┓ + #TO_BE_REPLACED# +┗━━━━━━━━━━━━━━━━━━┛ + ┏━━━━┓ ┏━━━━┓ + ┃ 搜索 ┃ ┃手气不错┃ + ┗━━━━┛ ┗━━━━┛ + +]], +"搜索"}, + +} + +function PrintAscii(input) + if #input <= 0 then + local metatables = {} + for k, v in pairs(_ASCII_IMAGE_TABLE) do + table.insert(metatables, {["suggest"] = k, ["help"] = v[2]}) + end + return metatables + elseif _ASCII_IMAGE_TABLE[input] then + local result = _ASCII_IMAGE_TABLE[input][1] + local last_commit = ime.get_last_commit() + if #last_commit <= 0 or #last_commit > 20 then + last_commit = "" + end + return result:gsub(_TO_BE_REPLACED_FLAG, last_commit) + else + error("Invalid argument") + end +end + +---------------------------------- +-- Bitmaps table used for ascii_large_letters(), in 5x7 bitmaps. +_LARGE_LETTER_BITMAPS = { + +[","] = [[ + + + + + ,, + , + , +]], + +["-"] = [[ + + + +----- + + + +]], + +["."] = [[ + + + + + +.. +.. +]], + +["0"] = [[ + 000 +0 0 +0 0 +0 0 +0 0 +0 0 + 000 +]], + +["1"] = [[ + 1 +111 + 1 + 1 + 1 + 1 +11111 +]], + +["2"] = [[ + 222 +2 2 + 2 + 2 + 2 + 2 +22222 +]], + +["3"] = [[ + 333 +3 3 + 3 + 33 + 3 +3 3 + 333 +]], + +["4"] = [[ + 4 + 44 + 4 4 +4 4 +44444 + 4 + 444 +]], + +["5"] = [[ +55555 +5 +5555 + 5 + 5 +5 5 + 555 +]], + +["6"] = [[ + 66 + 6 +6 +6666 +6 6 +6 6 + 666 +]], + +["7"] = [[ +77777 +7 7 + 7 + 7 + 7 + 7 + 7 +]], + +["8"] = [[ + 888 +8 8 +8 8 + 888 +8 8 +8 8 + 888 +]], + +["9"] = [[ + 999 +9 9 +9 9 + 9999 + 9 + 9 + 99 +]], + +["A"] = [[ + A + A + A A + A A +AAAAA +A A +A A +]], + +["B"] = [[ +BBBB +B B +B B +BBBB +B B +B B +BBBB +]], + +["C"] = [[ + CCC +C C +C +C +C +C C + CCC +]], + +["D"] = [[ +DDD +D D +D D +D D +D D +D D +DDD +]], + +["E"] = [[ +EEEEE +E +E +EEEE +E +E +EEEEE +]], + +["F"] = [[ +FFFFF +F +F +FFFF +F +F +F +]], + +["G"] = [[ + GGG +G G +G +G GG +G G +G G + GGG +]], + +["H"] = [[ +H H +H H +H H +HHHHH +H H +H H +H H +]], + +["I"] = [[ +IIIII + I + I + I + I + I +IIIII +]], + +["J"] = [[ +JJJJJ + J + J + J + J + J +JJ +]], + +["K"] = [[ +K K +K K +K K +KK +K K +K K +K K +]], + +["L"] = [[ +L +L +L +L +L +L +LLLLL +]], + +["M"] = [[ + M M + MMM + MMM + MMM +M M M +M M M +M M +]], + +["N"] = [[ +N N +N N +NN N +N N N +N NN +N N +N N +]], + +["O"] = [[ + OOO +O O +O O +O O +O O +O O + OOO +]], + +["P"] = [[ +PPPP +P P +P P +PPPP +P +P +P +]], + +["Q"] = [[ + QQQ +Q Q +Q Q +Q Q +Q Q Q +Q Q Q + QQQQ +]], + +["R"] = [[ +RRRR +R R +R R +RRRR +R R +R R +R R +]], + +["S"] = [[ + SSS +S S +S + SSS + S +S S + SSS +]], + +["T"] = [[ +TTTTT + T + T + T + T + T + T +]], + +["U"] = [[ +U U +U U +U U +U U +U U +U U + UUU +]], + +["V"] = [[ +V V +V V +V V + V V + V V + V V + V +]], + +["W"] = [[ +W W +W W W +W W W + WWW + WWW + WWW + W W +]], + +["X"] = [[ +X X +X X + X X + X + X X +X X +X X +]], + +["Y"] = [[ +Y Y +Y Y + Y Y + Y + Y + Y + Y +]], + +["Z"] = [[ +ZZZZZ + Z + Z + Z + Z +Z +ZZZZZ +]], + +} + +-- Converts input string to ascii image of large letters. +function PrintLetter(input_string) + if #input_string == 0 then + return {} + end + local letter_width = 5 + local letter_height = 7 + local max_string_length = 16 + local result_lines = {} + for i = 1, letter_height do result_lines[i] = "" end + input_string = input_string:upper() + -- Limits the input string size. + input_string = input_string:sub(1, max_string_length) + -- Only interate on valid characters. + for c in input_string:gmatch("[0-9A-Z ,.-]") do + local letter = _LARGE_LETTER_BITMAPS[c] + -- Splits the letter bitmap into lines and appends each line to the + -- corresponding line of the result. + local lines = ime.split_string(letter, "\n") + for i, line in ipairs(lines) do + if i > letter_height then break end + for i = 1, letter_width - #line do line = line .. ' ' end + result_lines[i] = result_lines[i] .. line .. ' ' + end + end + -- Merges result lines. + for i, line in ipairs(result_lines) do + result_lines[i] = ime.trim_string_right(result_lines[i]) + end + local result = "\n" .. ime.join_string(result_lines, "\n") .. "\n" + return result +end + +-- Dice images. +_DICE_BITMAPS = { + +[[ +/---------\ +| | +| | +| (O) | +| | +| | +\---------/ +]], + +[[ +/---------\ +| | +| @ | +| | +| @ | +| | +\---------/ +]], + +[[ +/---------\ +| | +| @ | +| @ | +| @ | +| | +\---------/ +]], + +[[ +/---------\ +| | +| @ @ | +| | +| @ @ | +| | +\---------/ +]], + +[[ +/---------\ +| | +| @ @ | +| @ | +| @ @ | +| | +\---------/ +]], + +[[ +/---------\ +| | +| @ @ | +| @ @ | +| @ @ | +| | +\---------/ +]], + +} + +math.randomseed(os.time()) + +-- Plays and shows n dices. +function PlayDice(n) + n = math.min(n, 6) + n = math.max(n, 1) + local dice_height = 7 + local result_lines = {} + for i = 1, dice_height do result_lines[i] = "" end + for i = 1, n do + local index = math.random(1, 6) + local dice = _DICE_BITMAPS[index] + -- Splits the dice bitmap into lines and appends each line to the + -- corresponding line of the result. + local lines = ime.split_string(dice, "\n") + for i, line in ipairs(lines) do + if i > dice_height then break end + result_lines[i] = result_lines[i] .. line .. ' ' + end + end + -- Merges result lines. + for i, line in ipairs(result_lines) do + result_lines[i] = ime.trim_string_right(result_lines[i]) + end + local result = "\n" .. ime.join_string(result_lines, "\n") .. "\n" + return result +end + +-------------------------- +_ZODIAC_TABLE = { + [{3, 21, 4, 19}] = "白羊座(Aries) ♈", + [{4, 20, 5, 20}] = "金牛座(Taurus) ♉", + [{5, 21, 6, 21}] = "双子座(Gemini) ♊", + [{6, 22, 7, 22}] = "巨蟹座(Cancer) ♋", + [{7, 23, 8, 22}] = "狮子座(Leo) ♌", + [{8, 23, 9, 23}] = "处女座(Virgo) ♍", + [{9, 24, 10, 23}] = "天秤座(Libra) ♎", + [{10, 24, 11, 21}] = "天蝎座(Scorpio) ♏", + [{11, 22, 12, 21}] = "射手座(Sagittarius) ♐", + [{12, 22, 12, 31}] = "摩羯座(Capricorn) ♑", + [{1, 1, 1, 19}] = "摩羯座(Capricorn) ♑", + [{1, 20, 2, 18}] = "水瓶座(Aquarius) ♒", + [{2, 19, 3, 20}] = "双鱼座(Pisces) ♓", +} + +_MONTH_TABLE_NORMAL = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +_MONTH_TABLE_LEAF = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + +function _CompareMonthAndDay(month1, day1, month2, day2) + if month1 < month2 then + return -1 + elseif month1 > month2 then + return 1 + elseif day1 < day2 then + return -1 + elseif day1 > day2 then + return 1 + else + return 0 + end +end + +-- birthday is a string in MM-DD format. +function QueryZodiac(birthday) + local month = 0 + local day = 0 + birthday:gsub("([0-9]+)-([0-9]+)$", + function(m, d) + month = tonumber(m) + day = tonumber(d) + end + ) + _VerifyDate(month, day) + for range, name in pairs(_ZODIAC_TABLE) do + local from_month = range[1] + local from_day = range[2] + local to_month = range[3] + local to_day = range[4] + if _CompareMonthAndDay(month, day, from_month, from_day) >=0 and + _CompareMonthAndDay(month, day, to_month, to_day) <=0 then + return name + end + end + error("Should never reach here") +end + + +----- + +-- Print Chinese manuscript grids. width_and_height in "WxH" format. +-- ┏━━━━━━━━━┓ +-- ┣━┳━┳━┳━┳━┫ +-- ┃ ┃ ┃ ┃ ┃ ┃ +-- ┣━┻━┻━┻━┻━┫ +-- ┣━┳━┳━┳━┳━┫ +-- ┃ ┃ ┃ ┃ ┃ ┃ +-- ┣━┻━┻━┻━┻━┫ +-- ┣━┳━┳━┳━┳━┫ +-- ┃ ┃ ┃ ┃ ┃ ┃ +-- ┣━┻━┻━┻━┻━┫ +-- ┗━━━━━━━━━┛ +function PrintGaozhi(width_and_height) + local width + local height + width_and_height:gsub("([0-9]+)[x%*]([0-9]+)$", + function(w, h) + width = w + height = h + end + ) + width = math.min(width, 20) + width = math.max(width, 1) + height = math.min(height, 20) + height = math.max(height, 1) + local result = "\n" + local print_line = function(leading, middle, middle_repeat, ending) + result = result .. leading + for i = 1, middle_repeat do + result = result .. middle + end + result = result .. ending + result = result .. "\n" + end + print_line("┏", "━", width * 2 - 1, "┓") + for i = 1, height do + print_line("┣", "━┳", width - 1, "━┫") + print_line("┃", " ┃", width, "") + print_line("┣", "━┻", width - 1, "━┫") + end + print_line("┗", "━", width * 2 - 1, "┛") + return result .. "\n" +end + +function GetCurrentTime() + return GetTime("") +end + +function GetToday() + return GetDate("") +end + +------------ +ime.register_command("sj", "GetTime", "输入时间", "alpha", "输入可选时间,例如12:34") +ime.register_command("rq", "GetDate", "输入日期", "alpha", "输入可选日期,例如2008-08-08") +ime.register_command("js", "Compute", "计算模式", "none", "输入表达式,例如3*log(4+2)") +ime.register_command("gz", "PrintGaozhi", "打印稿纸", "none", "输入稿纸大小,例如2x3") +ime.register_command("xz", "QueryZodiac", "查询星座", "none", "输入您的生日,例如12-14") +ime.register_command("sz", "PlayDice", "掷骰子", "none", "输入骰子个数,例如3") +ime.register_command("zf", "PrintLetter", "打印字符", "none", "请输入字母或数字序列,例如hello") +ime.register_command("hh", "PrintAscii", "画画") +ime.register_trigger("GetCurrentTime", "显示时间", {}, {'时间'}) +ime.register_trigger("GetToday", "显示日期", {}, {'日期'}) |
