diff --git a/double_pinyin.schema.yaml b/double_pinyin.schema.yaml index 3b0f09c..3378393 100644 --- a/double_pinyin.schema.yaml +++ b/double_pinyin.schema.yaml @@ -71,6 +71,7 @@ engine: - punct_translator - script_translator - lua_translator@date_translator # 时间、日期、星期 + - lua_translator@lunar # 农历 - table_translator@custom_phrase # 自定义短语 custom_phrase_double.txt - table_translator@melt_eng # 英文输入 - reverse_lookup_translator@liangfen # 反查,两分拼字 @@ -94,6 +95,10 @@ date_translator: timestamp: timestamp # 时间戳: 1669716794 +# Lua 配置:农历 +lunar: lunar # 癸卯年(兔)冬月廿一 二〇二四年冬月廿一 + + # Lua 配置: 降低部分英语单词在候选项的位置。 # 详细介绍 https://dvel.me/posts/make-rime-en-better/#短单词置顶的问题 # 正常情况: 输入 rug 得到 「1.rug 2.如果 …… 」 diff --git a/double_pinyin_abc.schema.yaml b/double_pinyin_abc.schema.yaml index f5923ad..f25fd10 100644 --- a/double_pinyin_abc.schema.yaml +++ b/double_pinyin_abc.schema.yaml @@ -70,6 +70,7 @@ engine: - punct_translator - script_translator - lua_translator@date_translator # 时间、日期、星期 + - lua_translator@lunar # 农历 - table_translator@custom_phrase # 自定义短语 custom_phrase_double.txt - table_translator@melt_eng # 英文输入 - reverse_lookup_translator@liangfen # 反查,两分拼字 @@ -93,6 +94,10 @@ date_translator: timestamp: timestamp # 时间戳: 1669716794 +# Lua 配置:农历 +lunar: lunar # 癸卯年(兔)冬月廿一 二〇二四年冬月廿一 + + # Lua 配置: 降低部分英语单词在候选项的位置。 # 详细介绍 https://dvel.me/posts/make-rime-en-better/#短单词置顶的问题 # 正常情况: 输入 rug 得到 「1.rug 2.如果 …… 」 diff --git a/double_pinyin_flypy.schema.yaml b/double_pinyin_flypy.schema.yaml index 046409f..46a8466 100644 --- a/double_pinyin_flypy.schema.yaml +++ b/double_pinyin_flypy.schema.yaml @@ -71,6 +71,7 @@ engine: - punct_translator - script_translator - lua_translator@date_translator # 时间、日期、星期 + - lua_translator@lunar # 农历 - table_translator@custom_phrase # 自定义短语 custom_phrase_double.txt - table_translator@melt_eng # 英文输入 - reverse_lookup_translator@liangfen # 反查,两分拼字 @@ -94,6 +95,10 @@ date_translator: timestamp: timestamp # 时间戳: 1669716794 +# Lua 配置:农历 +lunar: lunar # 癸卯年(兔)冬月廿一 二〇二四年冬月廿一 + + # Lua 配置: 降低部分英语单词在候选项的位置。 # 详细介绍 https://dvel.me/posts/make-rime-en-better/#短单词置顶的问题 # 正常情况: 输入 rug 得到 「1.rug 2.如果 …… 」 diff --git a/double_pinyin_mspy.schema.yaml b/double_pinyin_mspy.schema.yaml index 500142b..3fe5da8 100644 --- a/double_pinyin_mspy.schema.yaml +++ b/double_pinyin_mspy.schema.yaml @@ -71,6 +71,7 @@ engine: - punct_translator - script_translator - lua_translator@date_translator # 时间、日期、星期 + - lua_translator@lunar # 农历 - table_translator@custom_phrase # 自定义短语 custom_phrase_double.txt - table_translator@melt_eng # 英文输入 - reverse_lookup_translator@liangfen # 反查,两分拼字 @@ -94,6 +95,10 @@ date_translator: timestamp: timestamp # 时间戳: 1669716794 +# Lua 配置:农历 +lunar: lunar # 癸卯年(兔)冬月廿一 二〇二四年冬月廿一 + + # Lua 配置: 降低部分英语单词在候选项的位置。 # 详细介绍 https://dvel.me/posts/make-rime-en-better/#短单词置顶的问题 # 正常情况: 输入 rug 得到 「1.rug 2.如果 …… 」 diff --git a/double_pinyin_sogou.schema.yaml b/double_pinyin_sogou.schema.yaml index 7741325..da279dc 100644 --- a/double_pinyin_sogou.schema.yaml +++ b/double_pinyin_sogou.schema.yaml @@ -71,6 +71,7 @@ engine: - punct_translator - script_translator - lua_translator@date_translator # 时间、日期、星期 + - lua_translator@lunar # 农历 - table_translator@custom_phrase # 自定义短语 custom_phrase_double.txt - table_translator@melt_eng # 英文输入 - reverse_lookup_translator@liangfen # 反查,两分拼字 @@ -94,6 +95,10 @@ date_translator: timestamp: timestamp # 时间戳: 1669716794 +# Lua 配置:农历 +lunar: lunar # 癸卯年(兔)冬月廿一 二〇二四年冬月廿一 + + # Lua 配置: 降低部分英语单词在候选项的位置。 # 详细介绍 https://dvel.me/posts/make-rime-en-better/#短单词置顶的问题 # 正常情况: 输入 rug 得到 「1.rug 2.如果 …… 」 diff --git a/double_pinyin_ziguang.schema.yaml b/double_pinyin_ziguang.schema.yaml index 0e915eb..f0b9006 100644 --- a/double_pinyin_ziguang.schema.yaml +++ b/double_pinyin_ziguang.schema.yaml @@ -71,6 +71,7 @@ engine: - punct_translator - script_translator - lua_translator@date_translator # 时间、日期、星期 + - lua_translator@lunar # 农历 - table_translator@custom_phrase # 自定义短语 custom_phrase_double.txt - table_translator@melt_eng # 英文输入 - reverse_lookup_translator@liangfen # 反查,两分拼字 @@ -94,6 +95,10 @@ date_translator: timestamp: timestamp # 时间戳: 1669716794 +# Lua 配置:农历 +lunar: lunar # 癸卯年(兔)冬月廿一 二〇二四年冬月廿一 + + # Lua 配置: 降低部分英语单词在候选项的位置。 # 详细介绍 https://dvel.me/posts/make-rime-en-better/#短单词置顶的问题 # 正常情况: 输入 rug 得到 「1.rug 2.如果 …… 」 diff --git a/lua/lunar.lua b/lua/lunar.lua new file mode 100755 index 0000000..32b8694 --- /dev/null +++ b/lua/lunar.lua @@ -0,0 +1,659 @@ +--[[ + Lua 阿拉伯数字转中文实现 https://blog.csdn.net/lp12345678910/article/details/121396243 + 农历功能复制自 https://github.com/boomker/rime-fast-xhup +--]] + +-- 数字转中文: + +local numerical_units = { + "", + "十", + "百", + "千", + "万", + "十", + "百", + "千", + "亿", + "十", + "百", + "千", + "兆", + "十", + "百", + "千", +} + +local numerical_names = { + "零", + "一", + "二", + "三", + "四", + "五", + "六", + "七", + "八", + "九", +} + +local function convert_arab_to_chinese(number) + local n_number = tonumber(number) + assert(n_number, "传入参数非正确number类型!") + + -- 0 ~ 9 + if n_number < 10 then + return numerical_names[n_number + 1] + end + -- 一十九 => 十九 + if n_number < 20 then + local digit = string.sub(n_number, 2, 2) + if digit == "0" then + return "十" + else + return "十" .. numerical_names[digit + 1] + end + end + + --[[ + 1. 最大输入9位 + 超过9位,string的len加2位(因为有.0的两位) + 零 ~ 九亿九千九百九十九万九千九百九十九 + 0 ~ 999999999 + 2. 最大输入14位(超过14位会四舍五入) + 零 ~ 九十九兆九千九百九十九亿九千九百九十九万九千九百九十九万 + 0 ~ 99999999999999 + --]] + local len_max = 9 + local len_number = string.len(number) + assert( + len_number > 0 and len_number <= len_max, + "传入参数位数" .. len_number .. "必须在(0, " .. len_max .. "]之间!" + ) + + -- 01,数字转成表结构存储 + local numerical_tbl = {} + for i = 1, len_number do + numerical_tbl[i] = tonumber(string.sub(n_number, i, i)) + end + + local pre_zero = false + local result = "" + for index, digit in ipairs(numerical_tbl) do + local curr_unit = numerical_units[len_number - index + 1] + local curr_name = numerical_names[digit + 1] + if digit == 0 then + if not pre_zero then + result = result .. curr_name + end + pre_zero = true + else + result = result .. curr_name .. curr_unit + pre_zero = false + end + end + result = string.gsub(result, "零+$", "") + return result +end + +-- 农历: + +-- 天干名称 +local cTianGan = { + "甲", + "乙", + "丙", + "丁", + "戊", + "己", + "庚", + "辛", + "壬", + "癸", +} + +-- 地支名称 +local cDiZhi = { + "子", + "丑", + "寅", + "卯", + "辰", + "巳", + "午", + "未", + "申", + "酉", + "戌", + "亥", +} + +-- 属相名称 +local cShuXiang = { + "鼠", + "牛", + "虎", + "兔", + "龙", + "蛇", + "马", + "羊", + "猴", + "鸡", + "狗", + "猪", +} + +-- 农历日期名 +local cDayName = { + "初一", + "初二", + "初三", + "初四", + "初五", + "初六", + "初七", + "初八", + "初九", + "初十", + "十一", + "十二", + "十三", + "十四", + "十五", + "十六", + "十七", + "十八", + "十九", + "二十", + "廿一", + "廿二", + "廿三", + "廿四", + "廿五", + "廿六", + "廿七", + "廿八", + "廿九", + "三十", +} + +-- 农历月份名 +local cMonName = { + "正月", + "二月", + "三月", + "四月", + "五月", + "六月", + "七月", + "八月", + "九月", + "十月", + "冬月", + "腊月", +} + +-- 农历数据 +local wNongliData = { + "AB500D2", + "4BD0883", + "4AE00DB", + "A5700D0", + "54D0581", + "D2600D8", + "D9500CC", + "655147D", + "56A00D5", + "9AD00CA", + "55D027A", + "4AE00D2", + "A5B0682", + "A4D00DA", + "D2500CE", + "D25157E", + "B5500D6", + "56A00CC", + "ADA027B", + "95B00D3", + "49717C9", + "49B00DC", + "A4B00D0", + "B4B0580", + "6A500D8", + "6D400CD", + "AB5147C", + "2B600D5", + "95700CA", + "52F027B", + "49700D2", + "6560682", + "D4A00D9", + "EA500CE", + "6A9157E", + "5AD00D6", + "2B600CC", + "86E137C", + "92E00D3", + "C8D1783", + "C9500DB", + "D4A00D0", + "D8A167F", + "B5500D7", + "56A00CD", + "A5B147D", + "25D00D5", + "92D00CA", + "D2B027A", + "A9500D2", + "B550781", + "6CA00D9", + "B5500CE", + "535157F", + "4DA00D6", + "A5B00CB", + "457037C", + "52B00D4", + "A9A0883", + "E9500DA", + "6AA00D0", + "AEA0680", + "AB500D7", + "4B600CD", + "AAE047D", + "A5700D5", + "52600CA", + "F260379", + "D9500D1", + "5B50782", + "56A00D9", + "96D00CE", + "4DD057F", + "4AD00D7", + "A4D00CB", + "D4D047B", + "D2500D3", + "D550883", + "B5400DA", + "B6A00CF", + "95A1680", + "95B00D8", + "49B00CD", + "A97047D", + "A4B00D5", + "B270ACA", + "6A500DC", + "6D400D1", + "AF40681", + "AB600D9", + "93700CE", + "4AF057F", + "49700D7", + "64B00CC", + "74A037B", + "EA500D2", + "6B50883", + "5AC00DB", + "AB600CF", + "96D0580", + "92E00D8", + "C9600CD", + "D95047C", + "D4A00D4", + "DA500C9", + "755027A", + "56A00D1", + "ABB0781", + "25D00DA", + "92D00CF", + "CAB057E", + "A9500D6", + "B4A00CB", + "BAA047B", + "AD500D2", + "55D0983", + "4BA00DB", + "A5B00D0", + "5171680", + "52B00D8", + "A9300CD", + "795047D", + "6AA00D4", + "AD500C9", + "5B5027A", + "4B600D2", + "96E0681", + "A4E00D9", + "D2600CE", + "EA6057E", + "D5300D5", + "5AA00CB", + "76A037B", + "96D00D3", + "4AB0B83", + "4AD00DB", + "A4D00D0", + "D0B1680", + "D2500D7", + "D5200CC", + "DD4057C", + "B5A00D4", + "56D00C9", + "55B027A", + "49B00D2", + "A570782", + "A4B00D9", + "AA500CE", + "B25157E", + "6D200D6", + "ADA00CA", + "4B6137B", + "93700D3", + "49F08C9", + "49700DB", + "64B00D0", + "68A1680", + "EA500D7", + "6AA00CC", + "A6C147C", + "AAE00D4", + "92E00CA", + "D2E0379", + "C9600D1", + "D550781", + "D4A00D9", + "DA400CD", + "5D5057E", + "56A00D6", + "A6C00CB", + "55D047B", + "52D00D3", + "A9B0883", + "A9500DB", + "B4A00CF", + "B6A067F", + "AD500D7", + "55A00CD", + "ABA047C", + "A5A00D4", + "52B00CA", + "B27037A", + "69300D1", + "7330781", + "6AA00D9", + "AD500CE", + "4B5157E", + "4B600D6", + "A5700CB", + "54E047C", + "D1600D2", + "E960882", + "D5200DA", + "DAA00CF", + "6AA167F", + "56D00D7", + "4AE00CD", + "A9D047D", + "A2D00D4", + "D1500C9", + "F250279", + "D5200D1", +} + +-- 十进制转二进制 +local function Dec2bin(n) + local t, t1 + local tables = {} + t = tonumber(n) + while math.floor(t / 2) >= 1 do + t1 = t and math.fmod(t, 2) + if t1 > 0 then + if #tables > 0 then + table.insert(tables, 1, 1) + else + tables[1] = 1 + end + else + if #tables > 0 then + table.insert(tables, 1, 0) + else + tables[1] = 0 + end + end + t = math.floor(t / 2) + if t == 1 then + if #tables > 0 then + table.insert(tables, 1, 1) + else + tables[1] = 1 + end + end + end + return string.gsub(table.concat(tables), "^[0]+", "") +end + +-- 2/10/16进制互转 +local function system(x, inPuttype, outputtype) + local r + if tonumber(inPuttype) == 2 then + if tonumber(outputtype) == 10 then -- 2进制-->10进制 + r = tonumber(tostring(x), 2) + -- elseif tonumber(outputtype) == 16 then -- 2进制-->16进制 + -- r = bin2hex(tostring(x)) + end + elseif tonumber(inPuttype) == 10 then + if tonumber(outputtype) == 2 then -- 10进制-->2进制 + r = Dec2bin(tonumber(x)) + elseif tonumber(outputtype) == 16 then -- 10进制-->16进制 + r = string.format("%x", x) + end + elseif tonumber(inPuttype) == 16 then + if tonumber(outputtype) == 2 then -- 16进制-->2进制 + r = Dec2bin(tonumber(tostring(x), 16)) + elseif tonumber(outputtype) == 10 then -- 16进制-->10进制 + r = tonumber(tostring(x), 16) + end + end + return r +end + +-- 农历16进制数据分解 +local function Analyze(Data) + local rtn1, rtn2, rtn3, rtn4 + rtn1 = system(string.sub(Data, 1, 3), 16, 2) + if string.len(rtn1) < 12 then + rtn1 = "0" .. rtn1 + end + rtn2 = string.sub(Data, 4, 4) + rtn3 = system(string.sub(Data, 5, 5), 16, 10) + rtn4 = system(string.sub(Data, -2, -1), 16, 10) + if string.len(rtn4) == 3 then + rtn4 = "0" .. system(string.sub(Data, -2, -1), 16, 10) + end + -- string.gsub(rtn1, "^[0]*", "") + return { rtn1, rtn2, rtn3, rtn4 } +end + +-- 年天数判断 +local function IsLeap(y) + local year = tonumber(y) + if not year then + return nil + end + if math.fmod(year, 400) ~= 0 and math.fmod(year, 4) == 0 or math.fmod(year, 400) == 0 then + return 366 + else + return 365 + end +end + +-- 返回当年过了多少天 +local function leaveDate(y) + local day, total + total = 0 + if IsLeap(tonumber(string.sub(y, 1, 4))) > 365 then + day = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + else + day = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + end + if tonumber(string.sub(y, 5, 6)) > 1 then + for i = 1, tonumber(string.sub(y, 5, 6)) - 1 do + total = total + day[i] + end + total = total + tonumber(string.sub(y, 7, 8)) + else + return tonumber(string.sub(y, 7, 8)) + end + return tonumber(total) +end + +-- 计算日期差,两个8位数日期之间相隔的天数,date2>date1 +local function diffDate(date1, date2) + local n, total + total = 0 + date1 = tostring(date1) + date2 = tostring(date2) + if tonumber(date2) > tonumber(date1) then + n = tonumber(string.sub(date2, 1, 4)) - tonumber(string.sub(date1, 1, 4)) + if n > 1 then + for i = 1, n - 1 do + total = total + IsLeap(tonumber(string.sub(date1, 1, 4)) + i) + end + total = total + + leaveDate(tonumber(string.sub(date2, 1, 8))) + + IsLeap(tonumber(string.sub(date1, 1, 4))) + - leaveDate(tonumber(string.sub(date1, 1, 8))) + elseif n == 1 then + total = IsLeap(tonumber(string.sub(date1, 1, 4))) + - leaveDate(tonumber(string.sub(date1, 1, 8))) + + leaveDate(tonumber(string.sub(date2, 1, 8))) + else + total = leaveDate(tonumber(string.sub(date2, 1, 8))) - leaveDate(tonumber(string.sub(date1, 1, 8))) + -- print(date1 .. "-" .. date2) + end + elseif tonumber(date2) == tonumber(date1) then + return 0 + else + return -1 + end + return total +end + +-- 公历转农历,支持转化范围公元1900-2100年 +-- 公历日期 Gregorian:格式 YYYYMMDD +-- <返回值>农历日期 中文 天干地支属相 +local function Date2LunarDate(Gregorian) + Gregorian = tostring(Gregorian) + local Year, Month, Day, Pos, Data0, Data1, MonthInfo, LeapInfo, Leap, Newyear, LYear, thisMonthInfo + Year = tonumber(Gregorian.sub(Gregorian, 1, 4)) + Month = tonumber(Gregorian.sub(Gregorian, 5, 6)) + Day = tonumber(Gregorian.sub(Gregorian, 7, 8)) + if Year > 2100 or Year < 1899 or Month > 12 or Month < 1 or Day < 1 or Day > 31 or string.len(Gregorian) < 8 then + return "无效日期" + end + + -- 获取两百年内的农历数据 + Pos = Year - 1900 + 2 + Data0 = wNongliData[Pos - 1] + Data1 = wNongliData[Pos] + -- 判断农历年份 + local tb1 = Analyze(Data1) + MonthInfo = tb1[1] + LeapInfo = tb1[2] + Leap = tb1[3] + Newyear = tb1[4] + local Date1 = Year .. Newyear + local Date2 = Gregorian + local Date3 = diffDate(Date1, Date2) -- 和当年农历新年相差的天数 + if Date3 < 0 then + -- print(Data0 .. "-2") + tb1 = Analyze(Data0) + Year = Year - 1 + MonthInfo = tb1[1] + LeapInfo = tb1[2] + Leap = tb1[3] + Newyear = tb1[4] + Date1 = Year .. Newyear + Date2 = Gregorian + Date3 = diffDate(Date1, Date2) + -- print(Date2 .. "--" .. Date1 .. "--" .. Date3) + end + + Date3 = Date3 + 1 + LYear = Year -- 农历年份,就是上面计算后的值 + if Leap > 0 then -- 有闰月 + thisMonthInfo = string.sub(MonthInfo, 1, tonumber(Leap)) .. LeapInfo .. string.sub(MonthInfo, Leap + 1) + else + thisMonthInfo = MonthInfo + end + + local thisMonth, thisDays, LMonth, LDay, Isleap, LunarDate, LunarDate2, LunarYear, LunarMonth + for i = 1, 13 do + thisMonth = string.sub(thisMonthInfo, i, i) + thisDays = 29 + thisMonth + if Date3 > thisDays then + Date3 = Date3 - thisDays + else + if Leap > 0 then + if Leap >= i then + LMonth = i + Isleap = 0 + else + LMonth = i - 1 + if i - Leap == 1 then + Isleap = 1 + else + Isleap = 0 + end + end + else + LMonth = i + Isleap = 0 + end + LDay = math.floor(Date3) + break + end + end + + if Isleap > 0 then + LunarMonth = "闰" .. cMonName[LMonth] + else + LunarMonth = cMonName[LMonth] + end + + local _nis = tostring(os.date("%Y")) + local _LunarYears = "" + for i = 1, _nis:len() do + local _ni_digit = tonumber(_nis:sub(i, i)) + _LunarYears = _LunarYears .. convert_arab_to_chinese(_ni_digit) + end + + LunarYear = string.gsub(_LunarYears, "零", "〇") + LunarDate = cTianGan[math.fmod(LYear - 4, 10) + 1] + .. cDiZhi[math.fmod(LYear - 4, 12) + 1] + .. "年(" + .. cShuXiang[math.fmod(LYear - 4, 12) + 1] + .. ")" + .. LunarMonth + .. cDayName[LDay] + + LunarDate2 = LunarYear .. "年" .. LunarMonth .. cDayName[LDay] + return LunarDate, LunarDate2 +end + +-- 农历 +local function translator(input, seg, env) + local date1, date2 = Date2LunarDate(os.date("%Y%m%d")) + env.lunar_key_word = env.lunar_key_word or + (env.engine.schema.config:get_string(env.name_space:gsub('^*', '')) or 'nl') + if input == env.lunar_key_word then + local lunar_date = Candidate("", seg.start, seg._end, date1, "") + lunar_date.quality = 999 + yield(lunar_date) + local lunar_ymd = (Candidate("", seg.start, seg._end, date2, "")) + lunar_ymd.quality = 999 + yield(lunar_ymd) + end +end + +return translator diff --git a/rime.lua b/rime.lua index 5f61a5d..68266be 100644 --- a/rime.lua +++ b/rime.lua @@ -11,6 +11,9 @@ select_character = require("select_character") -- 日期时间,可在方案中配置触发关键字。 date_translator = require("date_translator") +-- 农历,可在方案中配置触发关键字。 +lunar = require("lunar") + -- Unicode,U 开头 unicode = require("unicode") diff --git a/rime_ice.schema.yaml b/rime_ice.schema.yaml index f5711e1..9699863 100644 --- a/rime_ice.schema.yaml +++ b/rime_ice.schema.yaml @@ -61,6 +61,7 @@ engine: - punct_translator - script_translator - lua_translator@date_translator # 时间、日期、星期 + - lua_translator@lunar # 农历 - table_translator@custom_phrase # 自定义短语 custom_phrase.txt - table_translator@melt_eng # 英文输入 - reverse_lookup_translator@liangfen # 反查,两分拼字 @@ -85,6 +86,10 @@ date_translator: timestamp: ts # 时间戳: 1669716794 +# Lua 配置:农历 +lunar: nl # 癸卯年(兔)冬月廿一 二〇二四年冬月廿一 + + # Lua 配置: 降低部分英语单词在候选项的位置。 # 详细介绍 https://dvel.me/posts/make-rime-en-better/#短单词置顶的问题 # 正常情况: 输入 rug 得到 「1.rug 2.如果 …… 」