CorvusSKKのinit.luaをカスタマイズして変換候補を追加する
できるようになったこと
-
abbrevモードでCapital CaseとUPPER CASEの候補を出す
-
郵便番号と住所をセットで変換する
ハイフンが含まれていてもOK -
SKKサーバ使用時にGoogle日本語入力APIが出してくる余計な候補を除外する
本>
本>
ポン>
ポン>
などの候補を出さない
やったこと
init.lua
の skk_search
関数をカスタムした。
local function to_skkdict_entry(t)
local ret = ""
if #t < 1 then
return ret
end
for i = 1, #t do
ret = ret .. "/" .. t[i]
end
return ret .. "/\n"
end
local function add_prefix_to_skkdict_entry(pref, ent)
return string.gsub(ent, "/%C", function(m)
return "/" .. pref .. string.sub(m, 2)
end)
end
local function skk_search(key, okuri)
local ret = ""
-- ユーザー辞書検索
ret = ret .. crvmgr.search_user_dictionary(key, okuri)
-- SKK辞書検索
local from_skk_dict = crvmgr.search_skk_dictionary(key, okuri)
ret = ret .. from_skk_dict
-- 郵便番号変換(郵便番号SKK辞書は数字7桁)
if 0 < string.len(from_skk_dict) and string.match(key, "^%d%d%d%d%d%d%d$") then
local pref = string.sub(key, 1, 3) .. "-" .. string.sub(key, 4) .. " "
ret = ret .. add_prefix_to_skkdict_entry(pref, from_skk_dict)
end
if string.match(key, "^%d%d%d%-%d%d%d%d$") then
local k = string.gsub(key, "-", "")
local s = crvmgr.search_skk_dictionary(k, okuri)
if 0 < string.len(s) then
local pref = key .. " "
ret = ret .. add_prefix_to_skkdict_entry(pref, s)
end
end
-- Capital Case と UPPER CASE を追加
if string.match(key, "^[a-z]+$") then
local c = string.upper(string.sub(key, 1, 1)) .. string.sub(key, 2)
ret = ret .. to_skkdict_entry({c, string.upper(key)})
end
--[[
SKK辞書サーバー検索
- 英数から始まる場合、接辞の>で終わる場合は Google 日本語入力 CGI APIへの問い合わせを除外する。
- crvskkserv.ini で正規表現を書く方法もあるが、設定の一元管理のために init.lua で設定しておく。
--]]
if not string.match(key, "^[a-zA-Z0-9#].+") then
local tail = string.sub(key, string.len(key))
if tail ~= ">" then
ret = ret .. crvmgr.search_skk_server(key)
end
end
if (okuri == "") then
-- Unicodeコードポイント変換
ret = ret .. crvmgr.search_unicode(key)
-- JIS X 0213面区点番号変換
ret = ret .. crvmgr.search_jisx0213(key)
-- JIS X 0208区点番号変換
ret = ret .. crvmgr.search_jisx0208(key)
local cccplen = string.len(charcode_conv_prefix)
if (cccplen < string.len(key) and string.sub(key, 1, cccplen) == charcode_conv_prefix) then
local subkey = string.sub(key, cccplen + 1)
-- 文字コード表記変換
ret = ret .. crvmgr.search_character_code(subkey)
end
end
-- 余計な"/\n"を削除
ret = string.gsub(ret, "/\n/", "/")
return ret
end
オリジナルとの差分
+ local function to_skkdict_entry(t)
+ local ret = ""
+ if #t < 1 then
+ return ret
+ end
+ for i = 1, #t do
+ ret = ret .. "/" .. t[i]
+ end
+ return ret .. "/\n"
+ end
+ local function add_prefix_to_skkdict_entry(pref, ent)
+ return string.gsub(ent, "/%C", function(m)
+ return "/" .. pref .. string.sub(m, 2)
+ end)
+ end
local function skk_search(key, okuri)
local ret = ""
-- ユーザー辞書検索
ret = ret .. crvmgr.search_user_dictionary(key, okuri)
-- SKK辞書検索
- ret = ret .. crvmgr.search_skk_dictionary(key, okuri)
+ local from_skk_dict = crvmgr.search_skk_dictionary(key, okuri)
+ ret = ret .. from_skk_dict
+ -- 郵便番号変換(郵便番号SKK辞書は数字7桁)
+ if 0 < string.len(from_skk_dict) and string.match(key, "^%d%d%d%d%d%d%d$") then
+ local pref = string.sub(key, 1, 3) .. "-" .. string.sub(key, 4) .. " "
+ ret = ret .. add_prefix_to_skkdict_entry(pref, from_skk_dict)
+ end
+ if string.match(key, "^%d%d%d%-%d%d%d%d$") then
+ local k = string.gsub(key, "-", "")
+ local s = crvmgr.search_skk_dictionary(k, okuri)
+ if 0 < string.len(s) then
+ local pref = key .. " "
+ ret = ret .. add_prefix_to_skkdict_entry(pref, s)
+ end
+ end
+ -- Capital Case と UPPER CASE を追加
+ if string.match(key, "^[a-z]+$") then
+ local c = string.upper(string.sub(key, 1, 1)) .. string.sub(key, 2)
+ ret = ret .. to_skkdict_entry({c, string.upper(key)})
+ end
- -- SKK辞書サーバー検索
- ret = ret .. crvmgr.search_skk_server(key)
+ --[[
+ SKK辞書サーバー検索
+ - 英数から始まる場合、接辞の>で終わる場合は Google 日本語入力 CGI APIへの問い合わせを除外する。
+ - crvskkserv.ini で正規表現を書く方法もあるが、設定の一元管理のために init.lua で設定しておく。
+ --]]
+ if not string.match(key, "^[a-zA-Z0-9#].+") then
+ local tail = string.sub(key, string.len(key))
+ if tail ~= ">" then
+ ret = ret .. crvmgr.search_skk_server(key)
+ end
+ end
if (okuri == "") then
-- Unicodeコードポイント変換
ret = ret .. crvmgr.search_unicode(key)
-- JIS X 0213面区点番号変換
ret = ret .. crvmgr.search_jisx0213(key)
-- JIS X 0208区点番号変換
ret = ret .. crvmgr.search_jisx0208(key)
local cccplen = string.len(charcode_conv_prefix)
if (cccplen < string.len(key) and string.sub(key, 1, cccplen) == charcode_conv_prefix) then
local subkey = string.sub(key, cccplen + 1)
-- 文字コード表記変換
ret = ret .. crvmgr.search_character_code(subkey)
end
end
-- 余計な"/\n"を削除
ret = string.gsub(ret, "/\n/", "/")
return ret
end
以下、解説。
解説
公式ソースコードのコメントにも書いてあるように、 skk_search
は /<C1><;A1>/<C2><;A2>/.../<Cn><;An>/\n
という形式の文字列を返す。
変換時にはこの文字列を /
で区切った各見出し語が表示されている。
つまり下図の場合は /阿;阿呆/婀;婀娜っぽい/痾;宿痾/唖;聾唖/……/\n
という文字列が返されている。
ので、この形式に沿うように文字列を整形してやればいい。
そのために関数を2つ追加する。
-- テーブルで渡した見出し語を辞書形式に変換する
local function to_skkdict_entry(t)
local ret = ""
if #t < 1 then
return ret
end
for i = 1, #t do
ret = ret .. "/" .. t[i]
end
return ret .. "/\n"
end
to_skkdict_entry({"あ", "い"})
は /あ/い/\n
となる。
-- エントリの各見出し語の先頭に任意の文字列を追加する
local function add_prefix_to_skkdict_entry(pref, ent)
return string.gsub(ent, "/%C", function(m)
return "/" .. pref .. string.sub(m, 2)
end)
end
add_prefix_to_skkdict_entry("hoge", "/あ/い/\n")
とすると出力は /hogeあ/hogeい/\n
。
正規表現で置換しているのは、たとえば 9610000 /福島県白河市/福島県西白河郡西郷村/
のように1つの郵便番号が複数の見出し語をもつケースが存在するため。
abbrevモードでCapital CaseとUPPER CASEの候補を出す
-- Capital Case と UPPER CASE を追加
if string.match(key, "^[a-z]+$") then
local c = string.upper(string.sub(key, 1, 1)) .. string.sub(key, 2)
ret = ret .. to_skkdict_entry({c, string.upper(key)})
end
skk_search
の引数の key
にはユーザー入力した文字列。
これがすべてアルファベットだったとき(poyo
)、1文字目を大文字にしたCapital Caseの見出し語(Poyo
)と全部大文字にしたUPPER CASEの見出し語(POYO
)を追加している。
郵便番号と住所をセットで変換する
郵便番号辞書を追加すると数字7桁で住所に変換できるようになる。
しかし辞書の見出し語は 東京都葛飾区
のような住所表記のみなので、Google日本語入力のように 124-0000 東京都葛飾区
というセットで変換することができない。
そこで、SKK辞書検索のプロセスにひと手間加える。
-- SKK辞書検索
local from_skk_dict = crvmgr.search_skk_dictionary(key, okuri)
ret = ret .. from_skk_dict
if 0 < string.len(from_skk_dict) and string.match(key, "^%d%d%d%d%d%d%d$") then
local pref = string.sub(key, 1, 3) .. "-" .. string.sub(key, 4) .. " "
ret = ret .. add_prefix_to_skkdict_entry(pref, from_skk_dict)
end
ローカルのSKK辞書を検索して、郵便番号にヒットすれば add_prefix_to_skkdict_entry()
で郵便番号(3桁-4桁フォーマット)を先頭に追加する。
コピペしてきた郵便番号を再変換するケースにも対応。
if string.match(key, "^%d%d%d%-%d%d%d%d$") then
local k = string.gsub(key, "-", "")
local s = crvmgr.search_skk_dictionary(k, okuri)
if 0 < string.len(s) then
local pref = key .. " "
ret = ret .. add_prefix_to_skkdict_entry(pref, s)
end
end
この場合は -
を除いた7桁の郵便番号で辞書を再検索し、結果に追加している。
SKKサーバ使用時にGoogle日本語入力APIが出してくる余計な候補を除外する
SKKサーバーはGoogle日本語入力APIに問い合わせるため、英数・記号を全角化した見出し語も候補に挙げてくる。
たとえば td
で現在の日付を実行変換するようにしていたときにも td
を候補として出してきたり、接辞変換で ぽん>
としたときに 本>
本>
ポン>
ポン>
といった記号を全角化した候補を挙げてくるなど、ノイズが混じってしまう。
そこで、ユーザーの入力が英数から始まるもしくは >
で終わる場合はサーバーに問い合わせないように条件分岐を設ける。
if not string.match(key, "^[a-zA-Z0-9#].+") then
local tail = string.sub(key, string.len(key))
if tail ~= ">" then
ret = ret .. crvmgr.search_skk_server(key)
end
end
SKKサーバーの設定で 見出し語の検索除外条件
をカスタムすることもできるが、正規表現がどんどん複雑になるうえに管理すべきファイルを増やしたくないのでこの方針で。
最新:
Discussion