メリークリスマス! atusyサンタからのクリスマスプレゼントはatusy/budoux.lua!
Budouxは文字列の改行を、人間にとって読みやすい位置で行うためのアルゴリズム。 Google製で、日本語や中国語、タイ語に対応し、PythonやJavaScript、Javaの実装が公式提供されている。
deno eval \
'import { loadDefaultJapaneseParser } from "npm:budoux";
console.log(loadDefaultJapaneseParser().parse("今日は天気です。"));'
# [ "今日は", "天気です。" ]
今回はatusy/budoux.luaとして、Luaに移植した(とりあえず日本語だけ)。
local budoux = require("budoux")
local parser = budoux.load_japanese_model()
parser.parse('今日は天気です。')
-- { "今日は", "天気です。" }
有名なあなたとJAVA,今すぐダウンロード
もうまく分割できる。
require("budoux").load_japanese_model().parse("あなたとJAVA,今すぐダウンロード")
-- { "あなたと", "JAVA,", "今すぐ", "ダウンロード" }
もう少し長文で「我輩は猫である」の冒頭を分割するととこんな感じ。
require("budoux").load_japanese_model().parse(
"吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。" ..
"何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。"
)
--[[
{
"吾輩は", "猫である。", "名前は", "まだ", "無い。", "どこで", "生れたかとんと", "見当が", "つかぬ。",
"何でも", "薄暗いじめじめした所で", "ニャーニャー泣いていた", "事だけは", "記憶している。"
}
]]
Budouxを使うと、Bionic readingの日本語版を軽量に実装できないかなと思っている。文節ごとに、先頭数文字を太字にして目が滑りにくくするイメージ。先の「我輩は猫である」の例だと以下の通り。
吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。
できればNeovimで実現したくて今回、Luaに移植した。
一方で、Neovim以外でも使えるように工夫した。だからbudoux.nvim
ではなくbudoux.lua
を名乗っている。
主に2点の工夫が必要だった。
- Unicode対応
- データ読み込み
LuaはUnicode文字をネイティブに扱えず、日本語を文字単位で文を分割することが難しい。そこで、lpegというパターンマッチングライブラリを使って分割した。
(lpeg.Ct(lpeg.C(lpeg.utfR(0, 0x10ffff)) ^ 0)):match("日本語")
-- { "日", "本", "語" }
ちなみにVim/Neovimであればsplit('日本語', '\zs')
のようにできる。
分割の判断基準となるデータは公式にはJSONで提供されているが、LuaはJSONパーサーを標準で持っていない。そこで、文字列置換でLuaテーブル化して、簡単に読み込めるようにした。
冬休みのうちにbionic readingを実装できるといいなあ。