1-- 2-- SPDX-FileCopyrightText: 2010 Peng Wu <alexepico@gmail.com> 3-- SPDX-FileCopyrightText: 2020 Weng Xuetian <wengxt@gmail.com> 4-- 5-- SPDX-License-Identifier: GPL-2.0-or-later 6-- 7---- encoding: UTF-8 8local fcitx = require("fcitx") 9 10local _CHINESE_DIGITS = { 11 [0] = "〇", 12 [1] = "一", 13 [2] = "二", 14 [3] = "三", 15 [4] = "四", 16 [5] = "五", 17 [6] = "六", 18 [7] = "七", 19 [8] = "八", 20 [9] = "九", 21 [10] = "十", 22} 23local _DATE_PATTERN = "^(%d+)-(%d+)-(%d+)$" 24local _TIME_PATTERN = "^(%d+):(%d+)$" 25local _MONTH_TABLE_LEAF = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } 26 27local function get_chinese_math_num(num) 28 local ret 29 if num < 10 then 30 ret = _CHINESE_DIGITS[num] 31 elseif num < 20 then 32 ret = _CHINESE_DIGITS[10] 33 if num > 10 then 34 ret = ret .. _CHINESE_DIGITS[num % 10] 35 end 36 elseif num < 100 then 37 local mod = num % 10 38 ret = _CHINESE_DIGITS[(num - mod) / 10] .. _CHINESE_DIGITS[10] 39 if mod > 0 then 40 ret = ret .. _CHINESE_DIGITS[mod] 41 end 42 else 43 error("Invalid number") 44 end 45 return ret 46end 47 48local function get_chinese_non_math_num(num) 49 local ret = "" 50 for ch in tostring(num):gmatch(".") do 51 if ch >= "0" and ch <= "9" then 52 ch = _CHINESE_DIGITS[tonumber(ch)] 53 end 54 ret = ret .. ch 55 end 56 return ret 57end 58 59local function _verify_time(hour, minute) 60 if hour < 0 or hour > 23 or minute < 0 or minute > 59 then 61 error("Invalid time") 62 end 63end 64 65local function _verify_date(month, day) 66 if month < 1 or month > 12 or day < 1 or day > _MONTH_TABLE_LEAF[month] then 67 error("Invalid date") 68 end 69end 70 71local function _verify_date_with_year(year, month, day) 72 _verify_date(month, day) 73 if year < 1 or year > 9999 then 74 error("Invalid year") 75 end 76 if month == 2 and day == 29 then 77 if year % 400 ~= 0 and year % 100 == 0 then 78 error("Invalid lunar day") 79 end 80 if year % 4 ~= 0 then 81 error("Invalid lunar day") 82 end 83 end 84end 85 86local function get_chinese_date(y, m, d, full) 87 if full then 88 return get_chinese_non_math_num(y) .. "年" .. 89 get_chinese_math_num(m) .. "月" .. 90 get_chinese_math_num(d) .. "日" 91 else 92 return y .. "年" .. m .. "月" .. d .. "日" 93 end 94end 95 96local function get_chinese_time(h, m, full) 97 if full then 98 local ret = get_chinese_math_num(h) .. "时" 99 if m > 0 then 100 ret = ret .. get_chinese_math_num(m) .. "分" 101 end 102 return ret 103 else 104 return h .. "时" .. m .. "分" 105 end 106end 107 108local function normalize_date(y, m, d) 109 return string.format("%d-%02d-%02d", y, m, d) 110end 111 112local function normalize_time(h, m) 113 return string.format("%02d:%02d", h, m) 114end 115 116function pinyin_get_time(input) 117 if fcitx.currentInputMethod() ~= "pinyin" and fcitx.currentInputMethod() ~= "shuangpin" then 118 return nil 119 end 120 121 local now = input 122 if #input == 0 then 123 now = os.date("%H:%M") 124 end 125 local hour, minute 126 now:gsub(_TIME_PATTERN, function(h, m) 127 hour = tonumber(h) 128 minute = tonumber(m) 129 end) 130 _verify_time(hour, minute) 131 return { 132 normalize_time(hour, minute), 133 get_chinese_time(hour, minute, false), 134 get_chinese_time(hour, minute, true), 135 } 136end 137 138function pinyin_get_date(input) 139 if fcitx.currentInputMethod() ~= "pinyin" and fcitx.currentInputMethod() ~= "shuangpin" then 140 return nil 141 end 142 143 local now = input 144 if #input == 0 then 145 now = os.date("%Y-%m-%d") 146 end 147 local year, month, day 148 now:gsub(_DATE_PATTERN, function(y, m, d) 149 year = tonumber(y) 150 month = tonumber(m) 151 day = tonumber(d) 152 end) 153 _verify_date_with_year(year, month, day) 154 return { 155 normalize_date(year, month, day), 156 get_chinese_date(year, month, day, false), 157 get_chinese_date(year, month, day, true), 158 } 159end 160 161function pinyin_get_current_time() 162 return pinyin_get_time("") 163end 164 165function pinyin_get_today() 166 return pinyin_get_date("") 167end 168 169local _MATH_SYMBOL = { 170"+", 171"-", 172"<", 173"=", 174">", 175"±", 176"×", 177"÷", 178"∈", 179"∏", 180"∑", 181"∕", 182"√", 183"∝", 184"∞", 185"∟", 186"∠", 187"∣", 188"∥", 189"∧", 190"∨", 191"∩", 192"∪", 193"∫", 194"∮", 195"∴", 196"∵", 197"∶", 198"∷", 199"∽", 200"≈", 201"≌", 202"≒", 203"≠", 204"≡", 205"≤", 206"≥", 207"≦", 208"≧", 209"≮", 210"≯", 211"⊕", 212"⊙", 213"⊥", 214"⊿", 215} 216 217local _ROMAN_NUMBER = { 218"ⅰ", 219"ⅱ", 220"ⅲ", 221"ⅳ", 222"ⅴ", 223"ⅵ", 224"ⅶ", 225"ⅷ", 226"ⅸ", 227"ⅹ", 228"ⅰ", 229"ⅱ", 230"ⅲ", 231"ⅳ", 232"ⅴ", 233"ⅵ", 234"ⅶ", 235"ⅷ", 236"ⅸ", 237"ⅹ", 238} 239 240local _UPPER_GREEK_LETTER = { 241"Α", 242"Β", 243"Γ", 244"Δ", 245"Ε", 246"Ζ", 247"Η", 248"Θ", 249"Ι", 250"Κ", 251"Λ", 252"Μ", 253"Ν", 254"Ξ", 255"Ο", 256"Π", 257"Ρ", 258"Σ", 259"Τ", 260"Υ", 261"Φ", 262"Χ", 263"Ψ", 264"Ω", 265} 266 267local _LOWER_GREEK_LETTER = { 268"α", 269"β", 270"γ", 271"δ", 272"ε", 273"ζ", 274"η", 275"θ", 276"ι", 277"κ", 278"λ", 279"μ", 280"ν", 281"ξ", 282"ο", 283"π", 284"ρ", 285"σ", 286"τ", 287"υ", 288"φ", 289"χ", 290"ψ", 291"ω", 292} 293 294local _UPPER_RUSSIAN_LETTER = { 295"А", 296"Б", 297"В", 298"Г", 299"Д", 300"Е", 301"Ж", 302"З", 303"И", 304"Й", 305"К", 306"Л", 307"М", 308"Н", 309"О", 310"П", 311"Р", 312"С", 313"Т", 314"У", 315"Ф", 316"Х", 317"Ц", 318"Ч", 319"Ш", 320"Щ", 321"Ъ", 322"Ы", 323"Ь", 324"Э", 325"Ю", 326"Я", 327"Ё", 328} 329 330local _LOWER_RUSSIAN_LETTER = { 331"а", 332"б", 333"в", 334"г", 335"д", 336"е", 337"ж", 338"з", 339"и", 340"й", 341"к", 342"л", 343"м", 344"н", 345"о", 346"п", 347"р", 348"с", 349"т", 350"у", 351"ф", 352"х", 353"ц", 354"ч", 355"ш", 356"щ", 357"ъ", 358"ы", 359"ь", 360"э", 361"ю", 362"я", 363"ё", 364} 365 366local _NUMBER_SYMBOL = { 367"①", 368"②", 369"③", 370"④", 371"⑤", 372"⑥", 373"⑦", 374"⑧", 375"⑨", 376"⑩", 377"⑴", 378"⑵", 379"⑶", 380"⑷", 381"⑸", 382"⑹", 383"⑺", 384"⑻", 385"⑼", 386"⑽", 387"⑾", 388"⑿", 389"⒀", 390"⒁", 391"⒂", 392"⒃", 393"⒄", 394"⒅", 395"⒆", 396"⒇", 397"⒈", 398"⒉", 399"⒊", 400"⒋", 401"⒌", 402"⒍", 403"⒎", 404"⒏", 405"⒐", 406"⒑", 407"⒒", 408"⒓", 409"⒔", 410"⒕", 411"⒖", 412"⒗", 413"⒘", 414"⒙", 415"⒚", 416"⒛", 417"㈠", 418"㈡", 419"㈢", 420"㈣", 421"㈤", 422"㈥", 423"㈦", 424"㈧", 425"㈨", 426"㈩", 427} 428 429local _CURRENCY_SYMBOL = { 430"$", 431"¢", 432"£", 433"¥", 434"¤", 435} 436 437local _ARROW_SYMBOL = { 438"←", 439"↑", 440"→", 441"↓", 442"↖", 443"↗", 444"↘", 445"↙", 446} 447 448function pinyin_get_symbol(input) 449 if fcitx.currentInputMethod() ~= "pinyin" and fcitx.currentInputMethod() ~= "shuangpin" then 450 return nil 451 end 452 453 if input == "" then 454 return { 455 {suggest="sx", help="数学符号"}, 456 {suggest="lmsz", help="罗马数字"}, 457 {suggest="dxxl", help="大写希腊"}, 458 {suggest="xxxl", help="小写希腊"}, 459 {suggest="dxew", help="大写俄文"}, 460 {suggest="xxew", help="小写俄文"}, 461 {suggest="sz", help="数字符号"}, 462 {suggest="hb", help="货币"}, 463 {suggest="jt", help="箭头"}, 464 } 465 elseif input == "sx" then 466 return _MATH_SYMBOL 467 elseif input == "lmsz" then 468 return _ROMAN_NUMBER 469 elseif input == "dxxl" then 470 return _UPPER_GREEK_LETTER 471 elseif input == "xxxl" then 472 return _LOWER_GREEK_LETTER 473 elseif input == "dxew" then 474 return _UPPER_RUSSIAN_LETTER 475 elseif input == "xxew" then 476 return _LOWER_RUSSIAN_LETTER 477 elseif input == "sz" then 478 return _NUMBER_SYMBOL 479 elseif input == "hb" then 480 return _CURRENCY_SYMBOL 481 elseif input == "jt" then 482 return _ARROW_SYMBOL 483 end 484 return nil 485end 486 487------------ 488ime.register_command("fh", "pinyin_get_symbol", "输入符号", "digit", "") 489 490ime.register_command("sj", "pinyin_get_time", "输入时间", "alpha", "输入可选时间,例如12:34") 491ime.register_command("rq", "pinyin_get_date", "输入日期", "alpha", "输入可选日期,例如2013-01-01") 492ime.register_trigger("pinyin_get_current_time", "显示时间", {}, {'时间'}) 493ime.register_trigger("pinyin_get_today", "显示日期", {}, {'日期'}) 494