Skip to content

Commit

Permalink
feat: cC键计算器 (#904)
Browse files Browse the repository at this point in the history
* feat(lua): calculator

* fix(calc_translator): 修复若干逻辑错误和添加部分功能

- 修复了函数(英文)未输入完整时造成的 result 为 nil 的错误
- 修复了未写参数时,result 类型错误
- 修复了算式(express)为空时(以及用户错误设置了正则表达式时),意外进入生成候选的逻辑
- 添加:随机数函数添加 random 表达
- 添加:候选默认隐藏插件前缀(via cand.prefix),设置 calculator/show_prefix 可以显示
- 功能:该插件所有候选置顶(via cand.quality)
- 功能:从 calculator/prefix 设定项获取前缀,而非自动获取,默认 `cC`

* style(calc_translator.lua):format style, rename calc_translator

---------

Co-authored-by: mirtlecn <[email protected]>
  • Loading branch information
ChaosAlphard and mirtlecn authored Nov 27, 2024
1 parent a37e5d0 commit a79d76e
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 14 deletions.
5 changes: 5 additions & 0 deletions default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,11 @@ key_binder:
- {accept: KP_8, send: 8, when: composing}
- {accept: KP_9, send: 9, when: composing}
- {accept: KP_Decimal, send: period, when: composing}
# 将小键盘 + - * / 映射到主键盘,使计算器 如 1+2-3*4 可使用小键盘输入
- {accept: KP_Multiply, send: asterisk, when: composing}
- {accept: KP_Add, send: plus, when: composing}
- {accept: KP_Subtract, send: minus, when: composing}
- {accept: KP_Divide, send: slash, when: composing}


# 按键速查
Expand Down
6 changes: 4 additions & 2 deletions double_pinyin.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ engine:
- table_translator@radical_lookup # 部件拆字反查
- lua_translator@unicode # Unicode
- lua_translator@number_translator # 数字、金额大写
- lua_translator@calc_translator # 计算器
- lua_translator@force_gc # 暴力 GC
filters:
- lua_filter@corrector # 错音错字提示
Expand Down Expand Up @@ -285,12 +286,13 @@ radical_reverse_lookup:
# 处理符合特定规则的输入码,如网址、反查

recognizer:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
punct: "^V([0-9]|10|[A-Za-z]+)$" # 响应 symbols_caps_v.yaml 的 symbols
radical_lookup: "^uU[a-z]+$" # 响应部件拆字的反查,与 radical_lookup/prefix 匹配
unicode: "^U[a-f0-9]+" # 脚本将自动获取第 2 个字符 U 作为触发前缀,响应 lua_translator@unicode,输出 Unicode 字符
number: "^R[0-9]+[.]?[0-9]*" # 脚本将自动获取第 2 个字符 R 作为触发前缀,响应 lua_translator@number_translator,数字金额大写
calculator: "^cC.+" # 响应 lua_translator@calc_translator,计算器。前缀设定项 calculator/prefix
gregorian_to_lunar: "^N[0-9]{1,8}" # 脚本将自动获取第 2 个字符 N 作为触发前缀,响应 lua_translator@lunar,公历转农历,输入 N20240115 得到「二〇二三年腊月初五」


Expand Down
6 changes: 4 additions & 2 deletions double_pinyin_abc.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ engine:
- table_translator@radical_lookup # 部件拆字反查
- lua_translator@unicode # Unicode
- lua_translator@number_translator # 数字、金额大写
- lua_translator@calc_translator # 计算器
- lua_translator@force_gc # 暴力 GC
filters:
- lua_filter@corrector # 错音错字提示
Expand Down Expand Up @@ -288,12 +289,13 @@ radical_reverse_lookup:
# 处理符合特定规则的输入码,如网址、反查

recognizer:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
punct: "^V([0-9]|10|[A-Za-z]+)$" # 响应 symbols_caps_v.yaml 的 symbols
radical_lookup: "^uU[a-z]+$" # 响应部件拆字的反查,与 radical_lookup/prefix 匹配
unicode: "^U[a-f0-9]+" # 脚本将自动获取第 2 个字符 U 作为触发前缀,响应 lua_translator@unicode,输出 Unicode 字符
number: "^R[0-9]+[.]?[0-9]*" # 脚本将自动获取第 2 个字符 R 作为触发前缀,响应 lua_translator@number_translator,数字金额大写
calculator: "^cC.+" # 响应 lua_translator@calc_translator,计算器。前缀设定项 calculator/prefix
gregorian_to_lunar: "^N[0-9]{1,8}" # 脚本将自动获取第 2 个字符 N 作为触发前缀,响应 lua_translator@lunar,公历转农历,输入 N20240115 得到「二〇二三年腊月初五」


Expand Down
6 changes: 4 additions & 2 deletions double_pinyin_flypy.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ engine:
- table_translator@radical_lookup # 部件拆字反查
- lua_translator@unicode # Unicode
- lua_translator@number_translator # 数字、金额大写
- lua_translator@calc_translator # 计算器
- lua_translator@force_gc # 暴力 GC
filters:
- lua_filter@corrector # 错音错字提示
Expand Down Expand Up @@ -285,12 +286,13 @@ radical_reverse_lookup:
# 处理符合特定规则的输入码,如网址、反查

recognizer:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
punct: "^V([0-9]|10|[A-Za-z]+)$" # 响应 symbols_caps_v.yaml 的 symbols
radical_lookup: "^uU[a-z]+$" # 响应部件拆字的反查,与 radical_lookup/prefix 匹配
unicode: "^U[a-f0-9]+" # 脚本将自动获取第 2 个字符 U 作为触发前缀,响应 lua_translator@unicode,输出 Unicode 字符
number: "^R[0-9]+[.]?[0-9]*" # 脚本将自动获取第 2 个字符 R 作为触发前缀,响应 lua_translator@number_translator,数字金额大写
calculator: "^cC.+" # 响应 lua_translator@calc_translator,计算器。前缀设定项 calculator/prefix
gregorian_to_lunar: "^N[0-9]{1,8}" # 脚本将自动获取第 2 个字符 N 作为触发前缀,响应 lua_translator@lunar,公历转农历,输入 N20240115 得到「二〇二三年腊月初五」


Expand Down
6 changes: 4 additions & 2 deletions double_pinyin_mspy.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ engine:
- table_translator@radical_lookup # 部件拆字反查
- lua_translator@unicode # Unicode
- lua_translator@number_translator # 数字、金额大写
- lua_translator@calc_translator # 计算器
- lua_translator@force_gc # 暴力 GC
filters:
- lua_filter@corrector # 错音错字提示
Expand Down Expand Up @@ -289,12 +290,13 @@ radical_reverse_lookup:
# 处理符合特定规则的输入码,如网址、反查

recognizer:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
punct: "^V([0-9]|10|[A-Za-z]+)$" # 响应 symbols_caps_v.yaml 的 symbols
radical_lookup: "^uU[a-z;]+$" # 响应部件拆字的反查,与 radical_lookup/prefix 匹配
unicode: "^U[a-f0-9]+" # 脚本将自动获取第 2 个字符 U 作为触发前缀,响应 lua_translator@unicode,输出 Unicode 字符
number: "^R[0-9]+[.]?[0-9]*" # 脚本将自动获取第 2 个字符 R 作为触发前缀,响应 lua_translator@number_translator,数字金额大写
calculator: "^cC.+" # 响应 lua_translator@calc_translator,计算器。前缀设定项 calculator/prefix
gregorian_to_lunar: "^N[0-9]{1,8}" # 脚本将自动获取第 2 个字符 N 作为触发前缀,响应 lua_translator@lunar,公历转农历,输入 N20240115 得到「二〇二三年腊月初五」


Expand Down
6 changes: 4 additions & 2 deletions double_pinyin_sogou.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ engine:
- table_translator@radical_lookup # 部件拆字反查
- lua_translator@unicode # Unicode
- lua_translator@number_translator # 数字、金额大写
- lua_translator@calc_translator # 计算器
- lua_translator@force_gc # 暴力 GC
filters:
- lua_filter@corrector # 错音错字提示
Expand Down Expand Up @@ -289,12 +290,13 @@ radical_reverse_lookup:
# 处理符合特定规则的输入码,如网址、反查

recognizer:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
punct: "^V([0-9]|10|[A-Za-z]+)$" # 响应 symbols_caps_v.yaml 的 symbols
radical_lookup: "^uU[a-z;]+$" # 响应部件拆字的反查,与 radical_lookup/prefix 匹配
unicode: "^U[a-f0-9]+" # 脚本将自动获取第 2 个字符 U 作为触发前缀,响应 lua_translator@unicode,输出 Unicode 字符
number: "^R[0-9]+[.]?[0-9]*" # 脚本将自动获取第 2 个字符 R 作为触发前缀,响应 lua_translator@number_translator,数字金额大写
calculator: "^cC.+" # 响应 lua_translator@calc_translator,计算器。前缀设定项 calculator/prefix
gregorian_to_lunar: "^N[0-9]{1,8}" # 脚本将自动获取第 2 个字符 N 作为触发前缀,响应 lua_translator@lunar,公历转农历,输入 N20240115 得到「二〇二三年腊月初五」


Expand Down
6 changes: 4 additions & 2 deletions double_pinyin_ziguang.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ engine:
- table_translator@radical_lookup # 部件拆字反查
- lua_translator@unicode # Unicode
- lua_translator@number_translator # 数字、金额大写
- lua_translator@calc_translator # 计算器
- lua_translator@force_gc # 暴力 GC
filters:
- lua_filter@corrector # 错音错字提示
Expand Down Expand Up @@ -287,12 +288,13 @@ radical_reverse_lookup:
# 处理符合特定规则的输入码,如网址、反查

recognizer:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
punct: "^V([0-9]|10|[A-Za-z]+)$" # 响应 symbols_caps_v.yaml 的 symbols
radical_lookup: "^uU[a-z;]+$" # 响应部件拆字的反查,与 radical_lookup/prefix 匹配
unicode: "^U[a-f0-9]+" # 脚本将自动获取第 2 个字符 U 作为触发前缀,响应 lua_translator@unicode,输出 Unicode 字符
number: "^R[0-9]+[.]?[0-9]*" # 脚本将自动获取第 2 个字符 R 作为触发前缀,响应 lua_translator@number_translator,数字金额大写
calculator: "^cC.+" # 响应 lua_translator@calc_translator,计算器。前缀设定项 calculator/prefix
gregorian_to_lunar: "^N[0-9]{1,8}" # 脚本将自动获取第 2 个字符 N 作为触发前缀,响应 lua_translator@lunar,公历转农历,输入 N20240115 得到「二〇二三年腊月初五」


Expand Down
209 changes: 209 additions & 0 deletions lua/calc_translator.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
-- 计算器插件
-- author: https://github.com/ChaosAlphard
local calc = {}

function calc.init( env )
local config = env.engine.schema.config
env.prefix = config:get_string( 'calculator/prefix' ) or 'cC'
env.show_prefix = config:get_bool( 'calculator/show_prefix' ) -- set to true to show prefix in preedit area
-- env.decimalPlaces = config:get_string('calculator/decimalPlaces') or '4'
end

local function startsWith( str, start ) return string.sub( str, 1, string.len( start ) ) == start end

local function truncateFromStart( str, truncateStr ) return string.sub( str, string.len( truncateStr ) + 1 ) end

local function yield_calc_cand( seg, cand_text, cand_comment, cand_preedit, show_prefix )
local cand = Candidate( 'calc', seg.start, seg._end, cand_text, cand_comment )
cand.quality = 99999
if not show_prefix then cand.preedit = cand_preedit end
yield( cand )
end

-- 函数表
local calcPlugin = {
-- e, exp(1) = e^1 = e
e = math.exp( 1 ),
-- π
pi = math.pi,
}

-- random([m [,n ]]) 返回m-n之间的随机数, n为空则返回1-m之间, 都为空则返回0-1之间的小数
local function random( ... ) return math.random( ... ) end
-- 注册到函数表中
calcPlugin['rdm'] = random
calcPlugin['random'] = random

-- 正弦
local function sin( x ) return math.sin( x ) end
calcPlugin['sin'] = sin

-- 双曲正弦
local function sinh( x ) return math.sinh( x ) end
calcPlugin['sinh'] = sinh

-- 反正弦
local function asin( x ) return math.asin( x ) end
calcPlugin['asin'] = asin

-- 余弦
local function cos( x ) return math.cos( x ) end
calcPlugin['cos'] = cos

-- 双曲余弦
local function cosh( x ) return math.cosh( x ) end
calcPlugin['cosh'] = cosh

-- 反余弦
local function acos( x ) return math.acos( x ) end
calcPlugin['acos'] = acos

-- 正切
local function tan( x ) return math.tan( x ) end
calcPlugin['tan'] = tan

-- 双曲正切
local function tanh( x ) return math.tanh( x ) end
calcPlugin['tanh'] = tanh

-- 反正切
-- 返回以弧度为单位的点相对于x轴的逆时针角度。x是点的横纵坐标比值
-- 返回范围从−π到π (以弧度为单位),其中负角度表示向下旋转,正角度表示向上旋转
local function atan( x ) return math.atan( x ) end
calcPlugin['atan'] = atan

-- 反正切
-- atan( y/x ) = atan2(y, x)
-- 返回以弧度为单位的点相对于x轴的逆时针角度。y是点的纵坐标,x是点的横坐标
-- 返回范围从−π到π (以弧度为单位),其中负角度表示向下旋转,正角度表示向上旋转
-- 与 math.atan(y/x) 函数相比,具有更好的数学定义,因为它能够正确处理边界情况(例如x=0)
local function atan2( y, x ) return math.atan2( y, x ) end
calcPlugin['atan2'] = atan2

-- 将角度从弧度转换为度 e.g. deg(π) = 180
local function deg( x ) return math.deg( x ) end
calcPlugin['deg'] = deg

-- 将角度从度转换为弧度 e.g. rad(180) = π
local function rad( x ) return math.rad( x ) end
calcPlugin['rad'] = rad

-- 返回两个值, 无法参与运算后续, 只能单独使用
-- 返回m,e 使得x = m * 2^e
local function frexp( x )
local m, e = math.frexp( x )
return m .. ' * 2^' .. e
end
calcPlugin['frexp'] = frexp

-- 返回 x * 2^y
local function ldexp( x, y ) return math.ldexp( x, y ) end
calcPlugin['ldexp'] = ldexp

-- 返回 e^x
local function exp( x ) return math.exp( x ) end
calcPlugin['exp'] = exp

-- 返回x的平方根 e.g. sqrt(x) = x^0.5
local function sqrt( x ) return math.sqrt( x ) end
calcPlugin['sqrt'] = sqrt

-- y为底x的对数, 使用换底公式实现
local function log( y, x )
-- 不能为负数或0
if x <= 0 or y <= 0 then return nil end

return math.log( x ) / math.log( y )
end
calcPlugin['log'] = log

-- e为底x的对数
local function loge( x )
-- 不能为负数或0
if x <= 0 then return nil end

return math.log( x )
end
calcPlugin['loge'] = loge

-- 10为底x的对数
local function log10( x )
-- 不能为负数或0
if x <= 0 then return nil end

return math.log10( x )
end
calcPlugin['log10'] = log10

-- 平均值
local function avg( ... )
local data = { ... }
local n = select( '#', ... )
-- 样本数量不能为0
if n == 0 then return nil end

-- 计算总和
local sum = 0
for _, value in ipairs( data ) do sum = sum + value end

return sum / n
end
calcPlugin['avg'] = avg

-- 方差
local function variance( ... )
local data = { ... }
local n = select( '#', ... )
-- 样本数量不能为0
if n == 0 then return nil end

-- 计算均值
local sum = 0
for _, value in ipairs( data ) do sum = sum + value end
local mean = sum / n

-- 计算方差
local sum_squared_diff = 0
for _, value in ipairs( data ) do sum_squared_diff = sum_squared_diff + (value - mean) ^ 2 end

return sum_squared_diff / n
end
calcPlugin['var'] = variance

-- 阶乘
local function factorial( x )
-- 不能为负数
if x < 0 then return nil end
if x == 0 or x == 1 then return 1 end

local result = 1
for i = 1, x do result = result * i end

return result
end
calcPlugin['fact'] = factorial

-- 实现阶乘计算(!)
local function replaceToFactorial( str )
-- 替换[0-9]!字符为fact([0-9])以实现阶乘
return str:gsub( '([0-9]+)!', 'fact(%1)' )
end

-- 简单计算器
function calc.func( input, seg, env )
if not seg:has_tag( 'calculator' ) or input == '' then return end
-- 提取算式
local express = truncateFromStart( input, env.prefix )
if express == '' then return end -- 防止用户写错了正则表达式造成错误
local code = replaceToFactorial( express )
local success, result = pcall( load( 'return ' .. code, 'calculate', 't', calcPlugin ) )
if success and result and (type( result ) == 'string' or type( result ) == 'number') and #tostring( result ) > 0 then
yield_calc_cand( seg, result, '', express, env.show_prefix )
yield_calc_cand( seg, express .. '=' .. result, '', express, env.show_prefix )
else
yield_calc_cand( seg, express, '解析失败', express, env.show_prefix )
yield_calc_cand( seg, code, '入参', express, env.show_prefix )
end
end

return calc
3 changes: 3 additions & 0 deletions rime.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ unicode = require("unicode")
-- 数字、人民币大写,R 开头
number_translator = require("number_translator")

-- 计算器
calc_translator = require("calc_translator")

-- filters:

-- 错音错字提示
Expand Down
6 changes: 4 additions & 2 deletions rime_ice.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ engine:
- table_translator@radical_lookup # 部件拆字反查
- lua_translator@unicode # Unicode
- lua_translator@number_translator # 数字、金额大写
- lua_translator@calc_translator # 计算器
- lua_translator@force_gc # 暴力 GC
filters:
- lua_filter@corrector # 错音错字提示
Expand Down Expand Up @@ -389,12 +390,13 @@ radical_reverse_lookup:

# 处理符合特定规则的输入码,如网址、反查
recognizer:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
import_preset: default # 从 default.yaml 继承通用的
patterns: # 再增加方案专有的:
punct: "^v([0-9]|10|[A-Za-z]+)$" # 响应 symbols_v.yaml 的 symbols,用 'v' 替换 '/'
radical_lookup: "^uU[a-z]+$" # 响应部件拆字的反查,与 radical_lookup/prefix 匹配
unicode: "^U[a-f0-9]+" # 脚本将自动获取第 2 个字符 U 作为触发前缀,响应 lua_translator@unicode,输出 Unicode 字符
number: "^R[0-9]+[.]?[0-9]*" # 脚本将自动获取第 2 个字符 R 作为触发前缀,响应 lua_translator@number_translator,数字金额大写
calculator: "^cC.+" # 响应 lua_translator@calc_translator,计算器。前缀设定项 calculator/prefix
gregorian_to_lunar: "^N[0-9]{1,8}" # 脚本将自动获取第 2 个字符 N 作为触发前缀,响应 lua_translator@lunar,公历转农历,输入 N20240115 得到「二〇二三年腊月初五」


Expand Down

0 comments on commit a79d76e

Please sign in to comment.