From efcb4e2bdd1859f8904575430babb1545b277f38 Mon Sep 17 00:00:00 2001 From: Dvel Date: Thu, 8 Feb 2024 18:39:49 +0800 Subject: [PATCH] =?UTF-8?q?style:=20Lua=20=E7=BB=9F=E4=B8=80=E7=BC=A9?= =?UTF-8?q?=E8=BF=9B=204=20=E7=A9=BA=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/autocap_filter.lua | 2 +- lua/cold_word_drop/debugtool.lua | 64 +- lua/cold_word_drop/drop_words.lua | 4 +- lua/cold_word_drop/filter.lua | 13 +- lua/cold_word_drop/hide_words.lua | 4 +- lua/cold_word_drop/metatable.lua | 28 +- lua/cold_word_drop/processor.lua | 3 +- lua/cold_word_drop/string.lua | 59 +- lua/cold_word_drop/turndown_freq_words.lua | 4 +- lua/long_word_filter.lua | 124 +-- lua/lunar.lua | 1146 ++++++++++---------- lua/number_translator.lua | 207 ++-- lua/pin_cand_filter.lua | 346 +++--- lua/search.lua | 4 +- lua/unicode.lua | 34 +- lua/v_filter.lua | 4 +- rime.lua | 20 +- 17 files changed, 1054 insertions(+), 1012 deletions(-) diff --git a/lua/autocap_filter.lua b/lua/autocap_filter.lua index 8b0dc16..2fcd0b9 100644 --- a/lua/autocap_filter.lua +++ b/lua/autocap_filter.lua @@ -5,7 +5,7 @@ - 部分规则不做转换 - 输入首字母大写,候选词转换为首字母大写: Hello → Hello - 输入至少前 2 个字母大写,候选词转换为全部大写: HEllo → HELLO - + 大写时无法动态调整词频 --]] local function autocap_filter(input, env) diff --git a/lua/cold_word_drop/debugtool.lua b/lua/cold_word_drop/debugtool.lua index 51b5534..cf7398f 100644 --- a/lua/cold_word_drop/debugtool.lua +++ b/lua/cold_word_drop/debugtool.lua @@ -42,39 +42,51 @@ -- puts(INFO,__FILE__(),__LINE__(),__FUNC__() , ...) -- -- global variable -function __FILE__(n) n=n or 2 return debug.getinfo(n,'S').source end -function __LINE__(n) n=n or 2 return debug.getinfo(n, 'l').currentline end -function __FUNC__(n) n=n or 2 return debug.getinfo(n, 'n').name end -INFO="log" -WARN="warn" -ERROR="error" -DEBUG="trace" -CONSOLE="console" +function __FILE__(n) + n = n or 2 + return debug.getinfo(n, 'S').source +end + +function __LINE__(n) + n = n or 2 + return debug.getinfo(n, 'l').currentline +end + +function __FUNC__(n) + n = n or 2 + return debug.getinfo(n, 'n').name +end + +INFO = "log" +WARN = "warn" +ERROR = "error" +DEBUG = "trace" +CONSOLE = "console" local function tran_msg(...) - local msg="\t" - for i,k in next, {...} do msg = msg .. ": " .. tostring(k) end - return msg + local msg = "\t" + for i, k in next, { ... } do msg = msg .. ": " .. tostring(k) end + return msg end -local function puts( tag , ...) - if type(tag) ~= "string" then return end +local function puts(tag, ...) + if type(tag) ~= "string" then return end - if INFO and tag:match("^" .. INFO) then - (log and log.info or print)( tag .. tran_msg(...)) - elseif WARN and tag:match("^" .. WARN) then - (log and log.warning or print)(tag .. tran_msg(...)) - elseif ERROR and tag:match("^" .. ERROR) then - (log and log.error or print)(tag .. tran_msg(...)) - elseif DEBUG and tag:match("^" .. DEBUG) then - (log and log.error or print)(tag .. tran_msg(...)) - elseif CONSOLE and tag:match( "^" .. CONSOLE ) then - ( print)( tag .. tran_msg(...)) - else - return - end + if INFO and tag:match("^" .. INFO) then + (log and log.info or print)(tag .. tran_msg(...)) + elseif WARN and tag:match("^" .. WARN) then + (log and log.warning or print)(tag .. tran_msg(...)) + elseif ERROR and tag:match("^" .. ERROR) then + (log and log.error or print)(tag .. tran_msg(...)) + elseif DEBUG and tag:match("^" .. DEBUG) then + (log and log.error or print)(tag .. tran_msg(...)) + elseif CONSOLE and tag:match("^" .. CONSOLE) then + (print)(tag .. tran_msg(...)) + else + return + end end return puts diff --git a/lua/cold_word_drop/drop_words.lua b/lua/cold_word_drop/drop_words.lua index f95740c..8f9e71d 100644 --- a/lua/cold_word_drop/drop_words.lua +++ b/lua/cold_word_drop/drop_words.lua @@ -1,4 +1,4 @@ local drop_words = -{ "示~例~", +{ "示~例~", } -return drop_words \ No newline at end of file +return drop_words diff --git a/lua/cold_word_drop/filter.lua b/lua/cold_word_drop/filter.lua index 2d2f4a6..c2fa950 100644 --- a/lua/cold_word_drop/filter.lua +++ b/lua/cold_word_drop/filter.lua @@ -1,4 +1,3 @@ - local drop_list = require("cold_word_drop.drop_words") local hide_list = require("cold_word_drop.hide_words") local turndown_freq_list = require("cold_word_drop.turndown_freq_words") @@ -24,8 +23,8 @@ local function filter(input, env) i = i + 1 ---@diagnostic disable-next-line: undefined-global yield(cand) - else - table.insert(cands, cand) + else + table.insert(cands, cand) end else table.insert(cands, cand) @@ -43,13 +42,13 @@ local function filter(input, env) (hide_list[cand.text] and table.find_index(hide_list[cand.text], cpreedit_code)) ) then - ---@diagnostic disable-next-line: undefined-global + ---@diagnostic disable-next-line: undefined-global yield(cand) end end - for cand in input:iter() do - yield(cand) - end + for cand in input:iter() do + yield(cand) + end end return filter diff --git a/lua/cold_word_drop/hide_words.lua b/lua/cold_word_drop/hide_words.lua index 690c00d..767a141 100644 --- a/lua/cold_word_drop/hide_words.lua +++ b/lua/cold_word_drop/hide_words.lua @@ -1,4 +1,4 @@ local hide_words = -{ ["示~例~"] = { "shil", "shili", }, +{ ["示~例~"] = { "shil", "shili", }, } -return hide_words \ No newline at end of file +return hide_words diff --git a/lua/cold_word_drop/metatable.lua b/lua/cold_word_drop/metatable.lua index ffb13ed..1ba2705 100644 --- a/lua/cold_word_drop/metatable.lua +++ b/lua/cold_word_drop/metatable.lua @@ -27,29 +27,29 @@ function metatable_chk(tab) end end -table.eachi = function (tab, func) +table.eachi = function(tab, func) for i = 1, #tab do func(tab[i], i) end return tab end -table.eacha = function (tab, func) +table.eacha = function(tab, func) for i, v in ipairs(tab) do func(v, i) end return tab end -table.each = function (tab, func) +table.each = function(tab, func) for k, v in pairs(tab) do func(v, k) end return tab end -table.find_index = function (tab, elm, ...) +table.find_index = function(tab, elm, ...) local _, i = table.find(tab, elm, ...) return i end -table.find = function (tab, elm, func) +table.find = function(tab, elm, func) for i, v in ipairs(tab) do if elm == v then return v, i @@ -57,17 +57,17 @@ table.find = function (tab, elm, func) end end -table.find_with_func = function (tab, elm, ...) +table.find_with_func = function(tab, elm, ...) local i, v = table.find(tab, elm) end -table.delete = function (tab, elm, ...) +table.delete = function(tab, elm, ...) local index = table.find_index(tab, elm) return index and table.remove(tab, index) end -table.find_all = function (tab, elm, ...) +table.find_all = function(tab, elm, ...) local tmptab = setmetatable({}, { __index = table }) - local _func = (type(elm) == "function" and elm) or function (v, k, ...) return v == elm end + local _func = (type(elm) == "function" and elm) or function(v, k, ...) return v == elm end for k, v in pairs(tab) do if _func(v, k, ...) then tmptab:insert(v) @@ -77,7 +77,7 @@ table.find_all = function (tab, elm, ...) end table.select = table.find_all -table.reduce = function (tab, func, arg) +table.reduce = function(tab, func, arg) local new, old = arg, arg for i, v in ipairs(tab) do new, old = func(v, new) @@ -85,17 +85,17 @@ table.reduce = function (tab, func, arg) return new, arg end -table.map = function (tab, func) +table.map = function(tab, func) local newtab = setmetatable({}, { __index = table }) - func = func or function (v, i) return v, i end + func = func or function(v, i) return v, i end for i, v in ipairs(tab) do newtab[i] = func(v, i) end return newtab end -table.map_hash = function (tab, func) -- table to list of array { key, v} +table.map_hash = function(tab, func) -- table to list of array { key, v} local newtab = setmetatable({}, { __index = table }) - func = func or function (k, v) return { k, v } end + func = func or function(k, v) return { k, v } end for k, v in pairs(tab) do newtab:insert(func(k, v)) end diff --git a/lua/cold_word_drop/processor.lua b/lua/cold_word_drop/processor.lua index c039038..233ed44 100644 --- a/lua/cold_word_drop/processor.lua +++ b/lua/cold_word_drop/processor.lua @@ -1,4 +1,3 @@ - require('cold_word_drop.string') require("cold_word_drop.metatable") -- local puts = require("tools/debugtool") @@ -146,7 +145,7 @@ local function processor(key, env) return 1 -- kAccept end - return 2 -- kNoop, 不做任何操作, 交给下个组件处理 + return 2 -- kNoop, 不做任何操作, 交给下个组件处理 end return processor diff --git a/lua/cold_word_drop/string.lua b/lua/cold_word_drop/string.lua index 8dd0033..9d4eb32 100644 --- a/lua/cold_word_drop/string.lua +++ b/lua/cold_word_drop/string.lua @@ -3,38 +3,39 @@ -- string.utf8_len = utf8.len -- string.utf8_offset= utf8.offset -- string.utf8_sub= utf8.sub -function string.split( str, sp,sp1) - sp =type(sp) == "string" and sp or " " - if #sp == 0 then - sp= "([%z\1-\127\194-\244][\128-\191]*)" - elseif #sp == 1 then - sp= "[^" .. (sp=="%" and "%%" or sp) .. "]*" - else - sp1= sp1 or "^" - str=str:gsub(sp,sp1) - sp= "[^".. sp1 .. "]*" - end +function string.split(str, sp, sp1) + sp = type(sp) == "string" and sp or " " + if #sp == 0 then + sp = "([%z\1-\127\194-\244][\128-\191]*)" + elseif #sp == 1 then + sp = "[^" .. (sp == "%" and "%%" or sp) .. "]*" + else + sp1 = sp1 or "^" + str = str:gsub(sp, sp1) + sp = "[^" .. sp1 .. "]*" + end - local tab= {} - for v in str:gmatch(sp) do - table.insert(tab,v) - end - return tab + local tab = {} + for v in str:gmatch(sp) do + table.insert(tab, v) + end + return tab end -function utf8.gsub(str,si,ei) - local function index(ustr,i) - return i>=0 and ( ustr:utf8_offset(i) or ustr:len() +1 ) - or ( ustr:utf8_offset(i) or 1 ) - end +function utf8.gsub(str, si, ei) + local function index(ustr, i) + return i >= 0 and (ustr:utf8_offset(i) or ustr:len() + 1) + or (ustr:utf8_offset(i) or 1) + end - local u_si= index(str,si) - ei = ei or str:utf8_len() - ei = ei >=0 and ei +1 or ei - local u_ei= index(str, ei ) -1 - return str:sub(u_si,u_ei) + local u_si = index(str, si) + ei = ei or str:utf8_len() + ei = ei >= 0 and ei + 1 or ei + local u_ei = index(str, ei) - 1 + return str:sub(u_si, u_ei) end -string.utf8_len= utf8.len -string.utf8_offset=utf8.offset -string.utf8_sub= utf8.gsub + +string.utf8_len = utf8.len +string.utf8_offset = utf8.offset +string.utf8_sub = utf8.gsub return true diff --git a/lua/cold_word_drop/turndown_freq_words.lua b/lua/cold_word_drop/turndown_freq_words.lua index f1acd96..ee6430e 100644 --- a/lua/cold_word_drop/turndown_freq_words.lua +++ b/lua/cold_word_drop/turndown_freq_words.lua @@ -1,4 +1,4 @@ local turndown_freq_words = -{ ["示~例~"] = { "shili", }, +{ ["示~例~"] = { "shili", }, } -return turndown_freq_words \ No newline at end of file +return turndown_freq_words diff --git a/lua/long_word_filter.lua b/lua/long_word_filter.lua index 0711132..0a55200 100644 --- a/lua/long_word_filter.lua +++ b/lua/long_word_filter.lua @@ -3,79 +3,79 @@ -- 不提升包含英文、数字、emoji、假名的候选项 local function isEmoji(text) - for _, char in utf8.codes(text) do - if (char >= 0x1F600 and char <= 0x1F64F) or -- Emoticons - (char >= 0x1F300 and char <= 0x1F5FF) or -- Misc Symbols and Pictographs - (char >= 0x1F680 and char <= 0x1F6FF) or -- Transport and Map - (char >= 0x2600 and char <= 0x26FF) or -- Misc symbols - (char >= 0x2700 and char <= 0x27BF) or -- Dingbats - (char >= 0xFE00 and char <= 0xFE0F) or -- Variation Selectors - (char >= 0x1F900 and char <= 0x1F9FF) or -- Supplemental Symbols and Pictographs - (char >= 0x1F1E6 and char <= 0x1F1FF) then -- Flags (iOS) - return true - end - end - return false + for _, char in utf8.codes(text) do + if (char >= 0x1F600 and char <= 0x1F64F) or -- Emoticons + (char >= 0x1F300 and char <= 0x1F5FF) or -- Misc Symbols and Pictographs + (char >= 0x1F680 and char <= 0x1F6FF) or -- Transport and Map + (char >= 0x2600 and char <= 0x26FF) or -- Misc symbols + (char >= 0x2700 and char <= 0x27BF) or -- Dingbats + (char >= 0xFE00 and char <= 0xFE0F) or -- Variation Selectors + (char >= 0x1F900 and char <= 0x1F9FF) or -- Supplemental Symbols and Pictographs + (char >= 0x1F1E6 and char <= 0x1F1FF) then -- Flags (iOS) + return true + end + end + return false end local function containsJapaneseKana(str) - for _, code in utf8.codes(str) do - -- 检查平假名的 Unicode 范围(0x3040 至 0x309F) - if code >= 0x3040 and code <= 0x309F then - return true - end - -- 检查片假名的 Unicode 范围(0x30A0 至 0x30FF) - if code >= 0x30A0 and code <= 0x30FF then - return true - end - end - return false + for _, code in utf8.codes(str) do + -- 检查平假名的 Unicode 范围(0x3040 至 0x309F) + if code >= 0x3040 and code <= 0x309F then + return true + end + -- 检查片假名的 Unicode 范围(0x30A0 至 0x30FF) + if code >= 0x30A0 and code <= 0x30FF then + return true + end + end + return false end local M = {} function M.init(env) - -- 提升 count 个词语,插入到第 idx 个位置,默认 2、4。 - local config = env.engine.schema.config - env.name_space = env.name_space:gsub("^*", "") - M.count = config:get_int(env.name_space .. "/count") or 2 - M.idx = config:get_int(env.name_space .. "/idx") or 4 + -- 提升 count 个词语,插入到第 idx 个位置,默认 2、4。 + local config = env.engine.schema.config + env.name_space = env.name_space:gsub("^*", "") + M.count = config:get_int(env.name_space .. "/count") or 2 + M.idx = config:get_int(env.name_space .. "/idx") or 4 end function M.func(input) - local l = {} - local firstWordLength = 0 -- 记录第一个候选词的长度,提前的候选词至少要比第一个候选词长 - local done = 0 -- 记录筛选了多少个词条(只提升 count 个词的权重) - local i = 1 - for cand in input:iter() do - local leng = utf8.len(cand.text) - -- 只以第一个候选项的长度作为参考 - if firstWordLength < 1 then - firstWordLength = leng - end - -- 不处理 M.idx 之前的候选项 - if i < M.idx then - i = i + 1 - yield(cand) - -- 长词直接 yield,其余的放到 l 里 - elseif leng <= firstWordLength or cand.text:find("[%a%d]") or containsJapaneseKana(cand.text) or isEmoji(cand.text) then - table.insert(l, cand) - else - yield(cand) - done = done + 1 - end - -- 找齐了或者 l 太大了,就不找了,一般前 50 个就够了 - if done == M.count or #l > 50 then - break - end - end - -- yield l 及后续的候选项 - for _, cand in ipairs(l) do - yield(cand) - end - for cand in input:iter() do - yield(cand) - end + local l = {} + local firstWordLength = 0 -- 记录第一个候选词的长度,提前的候选词至少要比第一个候选词长 + local done = 0 -- 记录筛选了多少个词条(只提升 count 个词的权重) + local i = 1 + for cand in input:iter() do + local leng = utf8.len(cand.text) + -- 只以第一个候选项的长度作为参考 + if firstWordLength < 1 then + firstWordLength = leng + end + -- 不处理 M.idx 之前的候选项 + if i < M.idx then + i = i + 1 + yield(cand) + -- 长词直接 yield,其余的放到 l 里 + elseif leng <= firstWordLength or cand.text:find("[%a%d]") or containsJapaneseKana(cand.text) or isEmoji(cand.text) then + table.insert(l, cand) + else + yield(cand) + done = done + 1 + end + -- 找齐了或者 l 太大了,就不找了,一般前 50 个就够了 + if done == M.count or #l > 50 then + break + end + end + -- yield l 及后续的候选项 + for _, cand in ipairs(l) do + yield(cand) + end + for cand in input:iter() do + yield(cand) + end end return M diff --git a/lua/lunar.lua b/lua/lunar.lua index 4d1c1cb..7a9c110 100755 --- a/lua/lunar.lua +++ b/lua/lunar.lua @@ -6,56 +6,56 @@ -- 数字转中文: local numerical_units = { - "", - "十", - "百", - "千", - "万", - "十", - "百", - "千", - "亿", - "十", - "百", - "千", - "兆", - "十", - "百", - "千", + "", + "十", + "百", + "千", + "万", + "十", + "百", + "千", + "亿", + "十", + "百", + "千", + "兆", + "十", + "百", + "千", } local numerical_names = { - "零", - "一", - "二", - "三", - "四", - "五", - "六", - "七", - "八", - "九", + "零", + "一", + "二", + "三", + "四", + "五", + "六", + "七", + "八", + "九", } local function convert_arab_to_chinese(number) - local n_number = tonumber(number) - assert(n_number, "传入参数非正确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 + -- 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的两位) 零 ~ 九亿九千九百九十九万九千九百九十九 @@ -64,608 +64,608 @@ local function convert_arab_to_chinese(number) 零 ~ 九十九兆九千九百九十九亿九千九百九十九万九千九百九十九万 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 .. "]之间!" - ) + 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 + -- 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 + 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", + "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]+", "") + 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 Atoi(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 + 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 = Atoi(string.sub(Data, 1, 3), 16, 2) - if string.len(rtn1) < 12 then - rtn1 = "0" .. rtn1 - end - rtn2 = string.sub(Data, 4, 4) - rtn3 = Atoi(string.sub(Data, 5, 5), 16, 10) - rtn4 = Atoi(string.sub(Data, -2, -1), 16, 10) - if string.len(rtn4) == 3 then - rtn4 = "0" .. Atoi(string.sub(Data, -2, -1), 16, 10) - end - -- string.gsub(rtn1, "^[0]*", "") - return { rtn1, rtn2, rtn3, rtn4 } + local rtn1, rtn2, rtn3, rtn4 + rtn1 = Atoi(string.sub(Data, 1, 3), 16, 2) + if string.len(rtn1) < 12 then + rtn1 = "0" .. rtn1 + end + rtn2 = string.sub(Data, 4, 4) + rtn3 = Atoi(string.sub(Data, 5, 5), 16, 10) + rtn4 = Atoi(string.sub(Data, -2, -1), 16, 10) + if string.len(rtn4) == 3 then + rtn4 = "0" .. Atoi(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 + 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) + 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 + 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 + 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 + -- 获取两百年内的农历数据 + 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 + 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 + 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 + if Isleap > 0 then + LunarMonth = "闰" .. cMonName[LMonth] + else + LunarMonth = cMonName[LMonth] + end - local _nis = tostring(LYear) - 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 + local _nis = tostring(LYear) + 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] + 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 + LunarDate2 = LunarYear .. "年" .. LunarMonth .. cDayName[LDay] + return LunarDate, LunarDate2 end -- 农历 -- 从 lunar: nl 获取农历触发关键字(双拼默认为 lunar) -- 从 recognizer/patterns/gregorian_to_lunar 获取第 2 个字符作为公历转农历的触发前缀,默认为 N local function translator(input, seg, env) - env.lunar_key_word = env.lunar_key_word or - (env.engine.schema.config:get_string(env.name_space:gsub('^*', '')) or 'nl') - env.gregorian_to_lunar = env.gregorian_to_lunar or - (env.engine.schema.config:get_string('recognizer/patterns/gregorian_to_lunar'):sub(2, 2) or 'N') - if input == env.lunar_key_word then - local date1, date2 = Date2LunarDate(os.date("%Y%m%d")) - local lunar_ymd = (Candidate("", seg.start, seg._end, date2, "")) - lunar_ymd.quality = 999 - yield(lunar_ymd) - local lunar_date = Candidate("", seg.start, seg._end, date1, "") - lunar_date.quality = 999 - yield(lunar_date) - elseif env.gregorian_to_lunar ~= '' and input:sub(1, 1) == env.gregorian_to_lunar then - local date1, date2 = Date2LunarDate(input:sub(2)) - local lunar_ymd = (Candidate("", seg.start, seg._end, date2, "")) - lunar_ymd.quality = 999 - yield(lunar_ymd) - local lunar_date = Candidate("", seg.start, seg._end, date1, "") - lunar_date.quality = 999 - yield(lunar_date) - end + env.lunar_key_word = env.lunar_key_word or + (env.engine.schema.config:get_string(env.name_space:gsub('^*', '')) or 'nl') + env.gregorian_to_lunar = env.gregorian_to_lunar or + (env.engine.schema.config:get_string('recognizer/patterns/gregorian_to_lunar'):sub(2, 2) or 'N') + if input == env.lunar_key_word then + local date1, date2 = Date2LunarDate(os.date("%Y%m%d")) + local lunar_ymd = (Candidate("", seg.start, seg._end, date2, "")) + lunar_ymd.quality = 999 + yield(lunar_ymd) + local lunar_date = Candidate("", seg.start, seg._end, date1, "") + lunar_date.quality = 999 + yield(lunar_date) + elseif env.gregorian_to_lunar ~= '' and input:sub(1, 1) == env.gregorian_to_lunar then + local date1, date2 = Date2LunarDate(input:sub(2)) + local lunar_ymd = (Candidate("", seg.start, seg._end, date2, "")) + lunar_ymd.quality = 999 + yield(lunar_ymd) + local lunar_date = Candidate("", seg.start, seg._end, date1, "") + lunar_date.quality = 999 + yield(lunar_date) + end end return translator diff --git a/lua/number_translator.lua b/lua/number_translator.lua index bef08bb..f48f5f9 100644 --- a/lua/number_translator.lua +++ b/lua/number_translator.lua @@ -3,116 +3,149 @@ -- 触发前缀默认为 recognizer/patterns/number 的第 2 个字符,即 R local function splitNumPart(str) - local part = {} - part.int, part.dot, part.dec = string.match(str, "^(%d*)(%.?)(%d*)") - return part + local part = {} + part.int, part.dot, part.dec = string.match(str, "^(%d*)(%.?)(%d*)") + return part end local function GetPreciseDecimal(nNum, n) - if type(nNum) ~= "number" then nNum =tonumber(nNum) end - n = n or 0; - n = math.floor(n) - if n < 0 then n = 0 end - local nDecimal = 10 ^ n - local nTemp = math.floor(nNum * nDecimal); - local nRet = nTemp / nDecimal; - return nRet; + if type(nNum) ~= "number" then nNum = tonumber(nNum) end + n = n or 0; + n = math.floor(n) + if n < 0 then n = 0 end + local nDecimal = 10 ^ n + local nTemp = math.floor(nNum * nDecimal); + local nRet = nTemp / nDecimal; + return nRet; end local function decimal_func(str, posMap, valMap) - local dec - posMap = posMap or {[1]="角"; [2]="分"; [3]="厘"; [4]="毫"} - valMap = valMap or {[0]="零"; "壹"; "贰"; "叁" ;"肆"; "伍"; "陆"; "柒"; "捌"; "玖"} - if #str>4 then dec = string.sub(tostring(str), 1, 4) else dec =tostring(str) end - dec = string.gsub(dec, "0+$", "") - - if dec == "" then return "整" end + local dec + posMap = posMap or { [1] = "角", [2] = "分", [3] = "厘", [4] = "毫" } + valMap = valMap or { [0] = "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" } + if #str > 4 then dec = string.sub(tostring(str), 1, 4) else dec = tostring(str) end + dec = string.gsub(dec, "0+$", "") - local result = "" - for pos =1, #dec do - local val = tonumber(string.sub(dec, pos, pos)) - if val~=0 then result = result .. valMap[val] .. posMap[pos] else result = result .. valMap[val] end - end - result=result:gsub(valMap[0]..valMap[0] ,valMap[0]) - return result:gsub(valMap[0]..valMap[0] ,valMap[0]) + if dec == "" then return "整" end + + local result = "" + for pos = 1, #dec do + local val = tonumber(string.sub(dec, pos, pos)) + if val ~= 0 then result = result .. valMap[val] .. posMap[pos] else result = result .. valMap[val] end + end + result = result:gsub(valMap[0] .. valMap[0], valMap[0]) + return result:gsub(valMap[0] .. valMap[0], valMap[0]) end -- 把数字串按千分位四位数分割,进行转换为中文 -local function formatNum(num,t) - local digitUnit,wordFigure - local result="" - num=tostring(num) - if tonumber(t) < 1 then digitUnit = {"", "十", "百","千"} else digitUnit = {"","拾","佰","仟"} end - if tonumber(t) <1 then - wordFigure = {"〇","一","二","三","四","五","六","七","八","九"} - else wordFigure = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"} end - if string.len(num)>4 or tonumber(num)==0 then return wordFigure[1] end - local lens=string.len(num) - for i=1,lens do - local n=wordFigure[tonumber(string.sub(num,-i,-i))+1] - if n~=wordFigure[1] then result=n .. digitUnit[i] .. result else result=n .. result end - end - result=result:gsub(wordFigure[1]..wordFigure[1] ,wordFigure[1]) - result=result:gsub(wordFigure[1].."$","") result=result:gsub(wordFigure[1].."$","") +local function formatNum(num, t) + local digitUnit, wordFigure + local result = "" + num = tostring(num) + if tonumber(t) < 1 then digitUnit = { "", "十", "百", "千" } else digitUnit = { "", "拾", "佰", "仟" } end + if tonumber(t) < 1 then + wordFigure = { "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九" } + else + wordFigure = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" } + end + if string.len(num) > 4 or tonumber(num) == 0 then return wordFigure[1] end + local lens = string.len(num) + for i = 1, lens do + local n = wordFigure[tonumber(string.sub(num, -i, -i)) + 1] + if n ~= wordFigure[1] then result = n .. digitUnit[i] .. result else result = n .. result end + end + result = result:gsub(wordFigure[1] .. wordFigure[1], wordFigure[1]) + result = result:gsub(wordFigure[1] .. "$", "") + result = result:gsub(wordFigure[1] .. "$", "") - return result + return result end -- 数值转换为中文 -local function number2cnChar(num,flag,digitUnit,wordFigure) --flag=0中文小写反之为大写 - local st,result - num=tostring(num) result="" - local num1,num2=math.modf(num) - if tonumber(num2)==0 then - if tonumber(flag) < 1 then - digitUnit = digitUnit or {[1]="万";[2]="亿"} wordFigure = wordFigure or {[1]="〇"; [2]="一"; [3]="十"; [4]="元"} - else - digitUnit = digitUnit or {[1]="万";[2]="亿"} wordFigure = wordFigure or {[1]="零"; [2]="壹"; [3]="拾"; [4]="元"} - end - local lens=string.len(num1) - if lens<5 then result=formatNum(num1,flag) elseif lens<9 then result=formatNum(string.sub(num1,1,-5),flag) .. digitUnit[1].. formatNum(string.sub(num1,-4,-1),flag) - elseif lens<13 then result=formatNum(string.sub(num1,1,-9),flag) .. digitUnit[2] .. formatNum(string.sub(num1,-8,-5),flag) .. digitUnit[1] .. formatNum(string.sub(num1,-4,-1),flag) else result="" end - result=result:gsub("^" .. wordFigure[1],"") result=result:gsub(wordFigure[1] .. digitUnit[1],"") result=result:gsub(wordFigure[1] .. digitUnit[2],"") - result=result:gsub(wordFigure[1] .. wordFigure[1],wordFigure[1]) result=result:gsub(wordFigure[1] .. "$","") - if lens>4 then result=result:gsub("^"..wordFigure[2].. wordFigure[3],wordFigure[3]) end - if result~="" then result=result .. wordFigure[4] else result="数值超限!" end - else return "数值超限!" end +local function number2cnChar(num, flag, digitUnit, wordFigure) --flag=0中文小写反之为大写 + local st, result + num = tostring(num) + result = "" + local num1, num2 = math.modf(num) + if tonumber(num2) == 0 then + if tonumber(flag) < 1 then + digitUnit = digitUnit or { [1] = "万", [2] = "亿" } + wordFigure = wordFigure or { [1] = "〇", [2] = "一", [3] = "十", [4] = "元" } + else + digitUnit = digitUnit or { [1] = "万", [2] = "亿" } + wordFigure = wordFigure or { [1] = "零", [2] = "壹", [3] = "拾", [4] = "元" } + end + local lens = string.len(num1) + if lens < 5 then + result = formatNum(num1, flag) + elseif lens < 9 then + result = formatNum(string.sub(num1, 1, -5), flag) .. digitUnit[1] .. formatNum(string.sub(num1, -4, -1), flag) + elseif lens < 13 then + result = formatNum(string.sub(num1, 1, -9), flag) .. + digitUnit[2] .. + formatNum(string.sub(num1, -8, -5), flag) .. digitUnit[1] .. formatNum(string.sub(num1, -4, -1), flag) + else + result = "" + end + result = result:gsub("^" .. wordFigure[1], "") + result = result:gsub(wordFigure[1] .. digitUnit[1], "") + result = result:gsub(wordFigure[1] .. digitUnit[2], "") + result = result:gsub(wordFigure[1] .. wordFigure[1], wordFigure[1]) + result = result:gsub(wordFigure[1] .. "$", "") + if lens > 4 then result = result:gsub("^" .. wordFigure[2] .. wordFigure[3], wordFigure[3]) end + if result ~= "" then result = result .. wordFigure[4] else result = "数值超限!" end + else + return "数值超限!" + end - return result + return result end -local function number2zh(num,t) - local result,wordFigure - result="" - if tonumber(t) <1 then - wordFigure = {"〇","一","二","三","四","五","六","七","八","九"} - else wordFigure = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"} end - if tostring(num)==nil then return "" end - for pos=1,string.len(num) do - result=result..wordFigure[tonumber(string.sub(num, pos, pos)+1)] - end - result=result:gsub(wordFigure[1] .. wordFigure[1],wordFigure[1]) - return result:gsub(wordFigure[1] .. wordFigure[1],wordFigure[1]) +local function number2zh(num, t) + local result, wordFigure + result = "" + if tonumber(t) < 1 then + wordFigure = { "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九" } + else + wordFigure = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" } + end + if tostring(num) == nil then return "" end + for pos = 1, string.len(num) do + result = result .. wordFigure[tonumber(string.sub(num, pos, pos) + 1)] + end + result = result:gsub(wordFigure[1] .. wordFigure[1], wordFigure[1]) + return result:gsub(wordFigure[1] .. wordFigure[1], wordFigure[1]) end local function number_translatorFunc(num) - local numberPart=splitNumPart(num) - local result={} - if numberPart.dot~="" then - table.insert(result,{number2cnChar(numberPart.int,0,{"万", "亿"},{"〇","一","十","点"})..number2zh(numberPart.dec,0),"〔数字小写〕"}) - table.insert(result,{number2cnChar(numberPart.int,1,{"萬", "億"},{"〇","一","十","点"})..number2zh(numberPart.dec,1),"〔数字大写〕"}) - else - table.insert(result,{number2cnChar(numberPart.int,0,{"万", "亿"},{"〇","一","十",""}),"〔数字小写〕"}) - table.insert(result,{number2cnChar(numberPart.int,1,{"萬", "億"},{"零","壹","拾",""}),"〔数字大写〕"}) - end - table.insert(result,{number2cnChar(numberPart.int,0)..decimal_func(numberPart.dec,{[1]="角"; [2]="分"; [3]="厘"; [4]="毫"},{[0]="〇"; "一"; "二"; "三" ;"四"; "五"; "六"; "七"; "八"; "九"}),"〔金额小写〕"}) - table.insert(result,{number2cnChar(numberPart.int,1)..decimal_func(numberPart.dec,{[1]="角"; [2]="分"; [3]="厘"; [4]="毫"},{[0]="零"; "壹"; "贰"; "叁" ;"肆"; "伍"; "陆"; "柒"; "捌"; "玖"}),"〔金额大写〕"}) - return result + local numberPart = splitNumPart(num) + local result = {} + if numberPart.dot ~= "" then + table.insert(result, + { number2cnChar(numberPart.int, 0, { "万", "亿" }, { "〇", "一", "十", "点" }) .. number2zh(numberPart.dec, 0), + "〔数字小写〕" }) + table.insert(result, + { number2cnChar(numberPart.int, 1, { "萬", "億" }, { "〇", "一", "十", "点" }) .. number2zh(numberPart.dec, 1), + "〔数字大写〕" }) + else + table.insert(result, { number2cnChar(numberPart.int, 0, { "万", "亿" }, { "〇", "一", "十", "" }), "〔数字小写〕" }) + table.insert(result, { number2cnChar(numberPart.int, 1, { "萬", "億" }, { "零", "壹", "拾", "" }), "〔数字大写〕" }) + end + table.insert(result, + { number2cnChar(numberPart.int, 0) .. + decimal_func(numberPart.dec, { [1] = "角", [2] = "分", [3] = "厘", [4] = "毫" }, + { [0] = "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九" }), "〔金额小写〕" }) + table.insert(result, + { number2cnChar(numberPart.int, 1) .. + decimal_func(numberPart.dec, { [1] = "角", [2] = "分", [3] = "厘", [4] = "毫" }, + { [0] = "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }), "〔金额大写〕" }) + return result end local function number_translator(input, seg, env) - -- 获取 recognizer/patterns/number 的第 2 个字符作为触发前缀 - env.number_keyword = env.number_keyword or env.engine.schema.config:get_string('recognizer/patterns/number'):sub(2, 2) + -- 获取 recognizer/patterns/number 的第 2 个字符作为触发前缀 + env.number_keyword = env.number_keyword or + env.engine.schema.config:get_string('recognizer/patterns/number'):sub(2, 2) local str, num, numberPart if env.number_keyword ~= '' and input:sub(1, 1) == env.number_keyword then str = string.gsub(input, "^(%a+)", "") diff --git a/lua/pin_cand_filter.lua b/lua/pin_cand_filter.lua index 93b5832..341715c 100644 --- a/lua/pin_cand_filter.lua +++ b/lua/pin_cand_filter.lua @@ -2,197 +2,197 @@ -- Powered By ChatGPT local function is_in_list(list, str) - for i, v in ipairs(list) do - if v == str then - return true, i - end - end - return false, 0 + for i, v in ipairs(list) do + if v == str then + return true, i + end + end + return false, 0 end local M = {} function M.init(env) - env.name_space = env.name_space:gsub("^*", "") - local list = env.engine.schema.config:get_list(env.name_space) - if not list then return end -- no configuration found -> stop + env.name_space = env.name_space:gsub("^*", "") + local list = env.engine.schema.config:get_list(env.name_space) + if not list then return end -- no configuration found -> stop - -- 如果定义了 'da zhuan' 或 'da zhong' ,会自动生成 'daz' 和 'dazh' 的键。 - -- 然而,如果明确定义了 'da z' 或 'da zh',则会优先使用这些明确自定义的简码,用 set 来做判断。 - local set = {} - for i = 0, list.size - 1 do - local preedit, texts = list:get_value_at(i).value:match("([^\t]+)\t(.+)") - if #preedit > 0 and #texts > 0 then - set[preedit:gsub(" ", "")] = true - end - end + -- 如果定义了 'da zhuan' 或 'da zhong' ,会自动生成 'daz' 和 'dazh' 的键。 + -- 然而,如果明确定义了 'da z' 或 'da zh',则会优先使用这些明确自定义的简码,用 set 来做判断。 + local set = {} + for i = 0, list.size - 1 do + local preedit, texts = list:get_value_at(i).value:match("([^\t]+)\t(.+)") + if #preedit > 0 and #texts > 0 then + set[preedit:gsub(" ", "")] = true + end + end - -- 遍历要置顶的候选项列表,将其转换为 table 存储到 M.pin_cands - -- 'l 了 啦' → M.pin_cands["l"] = {"了", "啦"} - -- 'ta 他 她 它' → M.pin_cands["ta"] = {"他", "她", "它"} - -- - -- 无空格的键,如 `nihao 你好` → M.pin_cands["nihao"] = {"你好"} - -- - -- 包含空格的的键,同时生成简码的拼写(最后一个空格后的首字母),如: - -- 'ni hao 你好 拟好' → M.pin_cands["nihao"] = {"你好", "拟好"} - -- → M.pin_cands["nih"] = {"你好", "拟好"} - -- - -- 如果最后一个空格后以 zh ch sh 开头,额外再生成 zh, ch, sh 的拼写,如: - -- 'zhi chi 支持' → M.pin_cands["zhichi"] = {"支持"} - -- → M.pin_cands["zhic"] = {"支持"} - -- → M.pin_cands["zhich"] = {"支持"} - -- - -- 如果同时定义了 'da zhuan 大专' 'da zhong 大众',会生成: - -- M.pin_cands["dazhuan"] = {"大专"} - -- M.pin_cands["dazhong"] = {"大众"} - -- M.pin_cands["daz"] = {"大专", "大众"} -- 先写的排在前面 - -- M.pin_cands["dazh"] = {"大专", "大众"} -- 先写的排在前面 - -- - -- 如果同时定义了 'da zhuan 大专' 'da zhong 大众' 且明确定义了简码形式 'da z 打字',会生成: - -- M.pin_cands["dazhuan"] = {"大专"} - -- M.pin_cands["dazhong"] = {"大众"} - -- M.pin_cands["daz"] = {"打字"} -- 明确定义的优先级更高 - -- M.pin_cands["dazh"] = {"大专", "大众"} -- 没明确定义的,仍然按上面的方式生成 + -- 遍历要置顶的候选项列表,将其转换为 table 存储到 M.pin_cands + -- 'l 了 啦' → M.pin_cands["l"] = {"了", "啦"} + -- 'ta 他 她 它' → M.pin_cands["ta"] = {"他", "她", "它"} + -- + -- 无空格的键,如 `nihao 你好` → M.pin_cands["nihao"] = {"你好"} + -- + -- 包含空格的的键,同时生成简码的拼写(最后一个空格后的首字母),如: + -- 'ni hao 你好 拟好' → M.pin_cands["nihao"] = {"你好", "拟好"} + -- → M.pin_cands["nih"] = {"你好", "拟好"} + -- + -- 如果最后一个空格后以 zh ch sh 开头,额外再生成 zh, ch, sh 的拼写,如: + -- 'zhi chi 支持' → M.pin_cands["zhichi"] = {"支持"} + -- → M.pin_cands["zhic"] = {"支持"} + -- → M.pin_cands["zhich"] = {"支持"} + -- + -- 如果同时定义了 'da zhuan 大专' 'da zhong 大众',会生成: + -- M.pin_cands["dazhuan"] = {"大专"} + -- M.pin_cands["dazhong"] = {"大众"} + -- M.pin_cands["daz"] = {"大专", "大众"} -- 先写的排在前面 + -- M.pin_cands["dazh"] = {"大专", "大众"} -- 先写的排在前面 + -- + -- 如果同时定义了 'da zhuan 大专' 'da zhong 大众' 且明确定义了简码形式 'da z 打字',会生成: + -- M.pin_cands["dazhuan"] = {"大专"} + -- M.pin_cands["dazhong"] = {"大众"} + -- M.pin_cands["daz"] = {"打字"} -- 明确定义的优先级更高 + -- M.pin_cands["dazh"] = {"大专", "大众"} -- 没明确定义的,仍然按上面的方式生成 - M.pin_cands = {} - for i = 0, list.size - 1 do - local preedit, texts = list:get_value_at(i).value:match("([^\t]+)\t(.+)") - if #preedit > 0 and #texts > 0 then - -- 按照 " > " 或 " " 分割词汇 - local delimiter = "\0" - if texts:find(" > ") then - texts = texts:gsub(" > ", delimiter) - else - texts = texts:gsub(" ", delimiter) - end - -- 按照键生成完整的拼写 - local preedit_no_spaces = preedit:gsub(" ", "") - M.pin_cands[preedit_no_spaces] = {} - for text in texts:gmatch("[^" .. delimiter .. "]+") do - table.insert(M.pin_cands[preedit_no_spaces], text) - end - -- 额外处理包含空格的 preedit,增加最后一个拼音的首字母和 zh, ch, sh 的简码 - if preedit:find(" ") then - local preceding_part, last_part = preedit:match("^(.+)%s(%S+)$") - if #last_part > 0 then - -- 生成最后一个拼音的简码拼写(最后一个空格后的首字母),如 ni hao 生成 nih - local p1 = preceding_part:gsub(" ", "") .. last_part:sub(1, 1) - -- 只在没有明确定义此简码时才生成,已有的追加,没有的直接赋值 - if not set[p1] then - if M.pin_cands[p1] ~= nil then - for text in texts:gmatch("[^" .. delimiter .. "]+") do - table.insert(M.pin_cands[p1], text) - end - else - M.pin_cands[p1] = M.pin_cands[preedit_no_spaces] - end - end - -- 生成最后一个拼音的 zh, ch, sh 的简码拼写(最后一个空格后以 zh ch sh 开头),如 zhi chi 生成 zhich - if last_part:match("^[zcs]h") then - local p2 = preceding_part:gsub(" ", "") .. last_part:sub(1, 2) - -- 只在没有明确定义此简码时才生成,已有的追加,没有的直接赋值 - if not set[p2] then - if M.pin_cands[p2] ~= nil then - for text in texts:gmatch("[^" .. delimiter .. "]+") do - table.insert(M.pin_cands[p2], text) - end - else - M.pin_cands[p2] = M.pin_cands[preedit_no_spaces] - end - end - end - end - end - end - end + M.pin_cands = {} + for i = 0, list.size - 1 do + local preedit, texts = list:get_value_at(i).value:match("([^\t]+)\t(.+)") + if #preedit > 0 and #texts > 0 then + -- 按照 " > " 或 " " 分割词汇 + local delimiter = "\0" + if texts:find(" > ") then + texts = texts:gsub(" > ", delimiter) + else + texts = texts:gsub(" ", delimiter) + end + -- 按照键生成完整的拼写 + local preedit_no_spaces = preedit:gsub(" ", "") + M.pin_cands[preedit_no_spaces] = {} + for text in texts:gmatch("[^" .. delimiter .. "]+") do + table.insert(M.pin_cands[preedit_no_spaces], text) + end + -- 额外处理包含空格的 preedit,增加最后一个拼音的首字母和 zh, ch, sh 的简码 + if preedit:find(" ") then + local preceding_part, last_part = preedit:match("^(.+)%s(%S+)$") + if #last_part > 0 then + -- 生成最后一个拼音的简码拼写(最后一个空格后的首字母),如 ni hao 生成 nih + local p1 = preceding_part:gsub(" ", "") .. last_part:sub(1, 1) + -- 只在没有明确定义此简码时才生成,已有的追加,没有的直接赋值 + if not set[p1] then + if M.pin_cands[p1] ~= nil then + for text in texts:gmatch("[^" .. delimiter .. "]+") do + table.insert(M.pin_cands[p1], text) + end + else + M.pin_cands[p1] = M.pin_cands[preedit_no_spaces] + end + end + -- 生成最后一个拼音的 zh, ch, sh 的简码拼写(最后一个空格后以 zh ch sh 开头),如 zhi chi 生成 zhich + if last_part:match("^[zcs]h") then + local p2 = preceding_part:gsub(" ", "") .. last_part:sub(1, 2) + -- 只在没有明确定义此简码时才生成,已有的追加,没有的直接赋值 + if not set[p2] then + if M.pin_cands[p2] ~= nil then + for text in texts:gmatch("[^" .. delimiter .. "]+") do + table.insert(M.pin_cands[p2], text) + end + else + M.pin_cands[p2] = M.pin_cands[preedit_no_spaces] + end + end + end + end + end + end + end end function M.func(input, env) - -- 当前输入框的 preedit,未经过方案 translator/preedit_format 转换 - -- 输入 nihaoshij 则为 nihaoshij,选择了「你好」后变成 你好shij - local full_preedit = env.engine.context:get_preedit().text - -- 非汉字部分的 preedit,如 shij - local letter_only_preedit = string.gsub(full_preedit, "[^a-zA-Z]", "") - -- 是否正在选词(已经选择了至少一个字词,如 `你好shij` 这种状态) - -- local isSelecting = full_preedit ~= letter_only_preedit + -- 当前输入框的 preedit,未经过方案 translator/preedit_format 转换 + -- 输入 nihaoshij 则为 nihaoshij,选择了「你好」后变成 你好shij + local full_preedit = env.engine.context:get_preedit().text + -- 非汉字部分的 preedit,如 shij + local letter_only_preedit = string.gsub(full_preedit, "[^a-zA-Z]", "") + -- 是否正在选词(已经选择了至少一个字词,如 `你好shij` 这种状态) + -- local isSelecting = full_preedit ~= letter_only_preedit - -- If there is no configuration, no filtering will be performed - if not M.pin_cands or #letter_only_preedit == 0 then - for cand in input:iter() do yield(cand) end - return - end + -- If there is no configuration, no filtering will be performed + if not M.pin_cands or #letter_only_preedit == 0 then + for cand in input:iter() do yield(cand) end + return + end - local pined = {} -- 提升的候选项 - local others = {} -- 其余候选项 - local pined_count = 0 + local pined = {} -- 提升的候选项 + local others = {} -- 其余候选项 + local pined_count = 0 - for cand in input:iter() do - local cand_preedit_no_spaces = cand.preedit:gsub(" ", "") + for cand in input:iter() do + local cand_preedit_no_spaces = cand.preedit:gsub(" ", "") - -- 无关的输入直接 break - if string.find(letter_only_preedit, "^" .. cand_preedit_no_spaces) == nil then - yield(cand) - break - end + -- 无关的输入直接 break + if string.find(letter_only_preedit, "^" .. cand_preedit_no_spaces) == nil then + yield(cand) + break + end - local texts = M.pin_cands[cand_preedit_no_spaces] + local texts = M.pin_cands[cand_preedit_no_spaces] - -- 跳过不需要处理的部分,对后续的候选项排序 - if texts == nil then - yield(cand) - else - -- 给 pined 几个空字符串占位元素,后面直接 pined[idx] = cand 确保 pined 与 texts 顺序一致 - if #pined < #texts then - for _ = 1, #texts do - table.insert(pined, '') - end - end - -- 处理简繁转换后的问题 - local cand_text = cand.text - if cand:get_dynamic_type() == "Shadow" then - -- handle cands converted by simplifier - local originalCand = cand:get_genuine() - if #originalCand.text == #cand_text and not is_in_list({ "↑", "←", "→", "↓", "丶", "✅", "✔", "⭕" }, cand.text) then - -- 笑|😄 cand_text = 😄; 麼|么 cand_text = 麼; - cand_text = originalCand.text - end - end - -- 要置顶的放到 pined 中,其余的放到 others - local ok, idx = is_in_list(texts, cand_text) - if ok then - pined[idx] = cand - pined_count = pined_count + 1 - else - table.insert(others, cand) - end - -- 找齐了或者 others 太大了,就不找了,一般前 5 个就找完了 - if pined_count == #texts or #others > 50 then - break - end - end - end + -- 跳过不需要处理的部分,对后续的候选项排序 + if texts == nil then + yield(cand) + else + -- 给 pined 几个空字符串占位元素,后面直接 pined[idx] = cand 确保 pined 与 texts 顺序一致 + if #pined < #texts then + for _ = 1, #texts do + table.insert(pined, '') + end + end + -- 处理简繁转换后的问题 + local cand_text = cand.text + if cand:get_dynamic_type() == "Shadow" then + -- handle cands converted by simplifier + local originalCand = cand:get_genuine() + if #originalCand.text == #cand_text and not is_in_list({ "↑", "←", "→", "↓", "丶", "✅", "✔", "⭕" }, cand.text) then + -- 笑|😄 cand_text = 😄; 麼|么 cand_text = 麼; + cand_text = originalCand.text + end + end + -- 要置顶的放到 pined 中,其余的放到 others + local ok, idx = is_in_list(texts, cand_text) + if ok then + pined[idx] = cand + pined_count = pined_count + 1 + else + table.insert(others, cand) + end + -- 找齐了或者 others 太大了,就不找了,一般前 5 个就找完了 + if pined_count == #texts or #others > 50 then + break + end + end + end - -- yield pined others 及后续的候选项 - if pined_count > 0 then - -- 如果因配置写了这个编码没有的字词,导致没有找齐,删掉空字符串占位元素 - local i = 1 - while i <= #pined do - if pined[i] == '' then - table.remove(pined, i) - else - i = i + 1 - end - end - for _, cand in ipairs(pined) do - yield(cand) - end - end - for _, cand in ipairs(others) do - yield(cand) - end - for cand in input:iter() do - yield(cand) - end + -- yield pined others 及后续的候选项 + if pined_count > 0 then + -- 如果因配置写了这个编码没有的字词,导致没有找齐,删掉空字符串占位元素 + local i = 1 + while i <= #pined do + if pined[i] == '' then + table.remove(pined, i) + else + i = i + 1 + end + end + for _, cand in ipairs(pined) do + yield(cand) + end + end + for _, cand in ipairs(others) do + yield(cand) + end + for cand in input:iter() do + yield(cand) + end end return M diff --git a/lua/search.lua b/lua/search.lua index abbcc22..a5b0bbb 100755 --- a/lua/search.lua +++ b/lua/search.lua @@ -59,7 +59,7 @@ function f.init(env) f.sort = config:get_bool(ns .. "/show_other_cands") - -- 反引号作为查找的引导符号,需要加入 speller 的字母表当中 + -- 反引号作为查找的引导符号,需要加入 speller 的字母表当中 f.search_key = config:get_string("key_binder/search") or config:get_string(ns .. "/key") or '`' -- 处理一下输入码,如果还有没有上屏的词,保留辅助码,否则,清除上屏码 @@ -95,7 +95,6 @@ function f.init(env) -- f.update_dict_entry(edit, no_search_string) end end) - end -- function f.update_dict_entry(s, code) @@ -233,7 +232,6 @@ function f.func(input, env) yield(cand) end end - end function f.fini(env) diff --git a/lua/unicode.lua b/lua/unicode.lua index 70b1701..ada3c9d 100644 --- a/lua/unicode.lua +++ b/lua/unicode.lua @@ -3,23 +3,23 @@ -- 示例:输入 U62fc 得到「拼」 -- 触发前缀默认为 recognizer/patterns/unicode 的第 2 个字符,即 U local function unicode(input, seg, env) - -- 获取 recognizer/patterns/unicode 的第 2 个字符作为触发前缀 - env.unicode_keyword = env.unicode_keyword or - env.engine.schema.config:get_string('recognizer/patterns/unicode'):sub(2, 2) - if seg:has_tag("unicode") and env.unicode_keyword ~= '' and input:sub(1, 1) == env.unicode_keyword then - local ucodestr = input:match(env.unicode_keyword .. "(%x+)") - if ucodestr and #ucodestr > 1 then - local code = tonumber(ucodestr, 16) - local text = utf8.char(code) - yield(Candidate("unicode", seg.start, seg._end, text, string.format("U%x", code))) - if code < 0x10000 then - for i = 0, 15 do - local text = utf8.char(code * 16 + i) - yield(Candidate("unicode", seg.start, seg._end, text, string.format("U%x~%x", code, i))) - end - end - end - end + -- 获取 recognizer/patterns/unicode 的第 2 个字符作为触发前缀 + env.unicode_keyword = env.unicode_keyword or + env.engine.schema.config:get_string('recognizer/patterns/unicode'):sub(2, 2) + if seg:has_tag("unicode") and env.unicode_keyword ~= '' and input:sub(1, 1) == env.unicode_keyword then + local ucodestr = input:match(env.unicode_keyword .. "(%x+)") + if ucodestr and #ucodestr > 1 then + local code = tonumber(ucodestr, 16) + local text = utf8.char(code) + yield(Candidate("unicode", seg.start, seg._end, text, string.format("U%x", code))) + if code < 0x10000 then + for i = 0, 15 do + local text = utf8.char(code * 16 + i) + yield(Candidate("unicode", seg.start, seg._end, text, string.format("U%x~%x", code, i))) + end + end + end + end end return unicode diff --git a/lua/v_filter.lua b/lua/v_filter.lua index 858695b..0e94988 100644 --- a/lua/v_filter.lua +++ b/lua/v_filter.lua @@ -4,7 +4,7 @@ -- 感谢改进 @[t123yh](https://github.com/t123yh) @[Shewer Lu](https://github.com/shewer) local function v_filter(input, env) local code = env.engine.context.input -- 当前编码 - env.v_spec_arr = env.v_spec_arr or Set({"0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣","Vs."}) + env.v_spec_arr = env.v_spec_arr or Set({ "0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣", "Vs." }) -- 仅当当前输入以 v 开头,并且编码长度为 2,才进行处理 if (string.len(code) == 2 and string.find(code, "^v")) then local l = {} @@ -12,7 +12,7 @@ local function v_filter(input, env) -- 特殊情况处理 if (env.v_spec_arr[cand.text]) then yield(cand) - -- 候选项为单个字符的,提到前面来。 + -- 候选项为单个字符的,提到前面来。 elseif (utf8.len(cand.text) == 1) then yield(cand) else diff --git a/rime.lua b/rime.lua index 56a9809..e85c335 100644 --- a/rime.lua +++ b/rime.lua @@ -83,18 +83,18 @@ cold_word_drop_filter = require("cold_word_drop.filter") -- 详情 https://github.com/hchunhui/librime-lua/issues/307 -- 这样也不会导致卡顿,那就每次都调用一下吧,内存稳稳的 function force_gc() - -- collectgarbage() - collectgarbage("step") + -- collectgarbage() + collectgarbage("step") end -- 临时用的 function debug_checker(input, env) - for cand in input:iter() do - yield(ShadowCandidate( - cand, - cand.type, - cand.text, - env.engine.context.input .. " - " .. env.engine.context:get_preedit().text .. " - " .. cand.preedit - )) - end + for cand in input:iter() do + yield(ShadowCandidate( + cand, + cand.type, + cand.text, + env.engine.context.input .. " - " .. env.engine.context:get_preedit().text .. " - " .. cand.preedit + )) + end end