/* はてなダイアリーキーワードふりがなリスト http://d.hatena.ne.jp/hatenadiary/20060922/1158908401 を、SKK辞書に変換する。 【使用法】 1. CSVファイルをダウンロード http://d.hatena.ne.jp/images/keyword/keywordlist_furigana.csv 2. CSVファイルと同じ場所に本スクリプトを置いて実行 3. 生成されたskk-keyword.txtを辞書フォルダへ (skk-keyword-alpha.txtは使わない) 元のCSVファイルのデータには破損したキーワードが多々含まれているため (長めの単語が途中で切れている)、正直このままでは利用に耐えないと思わ れる。とはいえ量が豊富なので人によっては役立つかもしれない。 利用の際は元データが破損していることを十分承知の上で使うこと。 元が「キーワード」なので、そのまま安直にSKK辞書にするとアルファベッ トの読みまで登録されてしまってむせる。そのため、日本語以外の文字(具 体的にはU+20〜U+FFの範囲)のみで構成された単語は別の辞書(Abbrevモー ド用)として分離している。こちらの利用は推奨しない。 */ F = new ActiveXObject("Scripting.FileSystemObject") /// CSVテキスト辞書からSKK辞書に変換 function csv2skk(infile, outfile, alpha) { // 文字コードを変換し行単位に分割 var a with (new ActiveXObject("ADODB.Stream")) { Type = 2 Charset = "iso-8859-1" Open() LoadFromFile(infile) var t = ReadText(2) Close() Charset = t == "\xFF\xFE" ? "utf-16" : "_autodetect" Open() LoadFromFile(infile) a = ReadText(-1).split(/\r|\n|\r\n/) Close() } // 変換 function r(c) { /// @todo 全角英字の変換結果が多すぎる。半角に直すなどの工夫が必要ではないか? c = c .replace(/ /g, " ") ///< @note 変換結果に\xA0?おかしいだろ常考 .replace(/"/g, "\"") .replace(/&/g, "&") .replace(/>/g, ">") .replace(/</g, "<") .replace(/²/g, "\xB2") .replace(/Ä/g, "\xC4") .replace(/Ï/g, "\xCF") .replace(/Ö/g, "\xD6") .replace(/Ø/g, "\xD8") .replace(/Ü/g, "\xDC") .replace(/ß/g, "\xDF") .replace(/á/g, "\xE1") .replace(/ä/g, "\xE4") .replace(/è/g, "\xE8") .replace(/é/g, "\xE9") .replace(/ö/g, "\xF6") .replace(/ø/g, "\xF8") .replace(/ú/g, "\xFA") .replace(/“/g, "\x201C") .replace(/”/g, "\x201D") .replace(/♥/g, "\x2665") .replace(/ /g, " ") var m = c.match(/&#\w+;/g) if (m) for (var n = 0; n < m.length; n++) { var x = m[n].slice(2, -1) c = c.replace(/&#\w+;/, x < 65536 ? String.fromCharCode(x) : String.fromCharCode(55232 + (x >> 10)) + String.fromCharCode(56320 | (x & 1023))) } // if (c.match(/&\w+;/)) WScript.Echo("警告: " + c) return c } var d = {}, o = [";; okuri-ari entries.", ";; okuri-nasi entries."] if (!alpha) for (var l in a) { var z = a[l].split("\t"), b = z[0], c = z[1] if (b.charAt(0) == "!" || b.length == 0 || c.length == 0) { o.push(";" + a[l]) continue } c = r(c) /// @todo 尻切れになったおかしなエントリが多すぎる。なんとか除外できないか? if (c.match(/^([\x20-\xFF]|\b|\.){2,}$/)) b = ";" + b if (b == c) b = ";" + b if (c.match(/^\[|^\]|\/|;/)) c = "(concat \"" + c.replace(/\"/g, "\\042").replace(/\\/g, "\\134") + "\")" d[b] = (b in d ? d[b] + "/" : "") + c } else for (var l in a) { var z = a[l].split("\t"), b = z[0], c = z[1] if (b.charAt(0) == "!" || b.length == 0 || c.length == 0) continue c = r(c) if (!c.match(/^([\x20-\xFF]|\b|\.){2,}$/)) continue /// @note 範囲を20〜FFにした場合、ウムラウト等の記号つき文字の変換が必要 if (!c.match(/&#/)) b = c.toLowerCase().replace(/@/g, "a").replace(/\W/g, "") else b = ";" + b if (b == c || b.match(/^\d+$/) || b.length == 0) b = ";" + b if (c.match(/^\[|^\]|\/|;/)) c = "(concat \"" + c.replace(/\"/g, "\\042").replace(/\\/g, "\\134") + "\")" d[b] = (b in d ? d[b] + "/" : "") + c } // 整形 for (var t in d) o.push(t + " /" + d[t] + "/") // 出力 with (F.CreateTextFile(outfile, true, true)) { Write(o.join("\r\n")) Close() } } csv2skk("keywordlist_furigana.csv", "skk-keyword.txt") csv2skk("keywordlist_furigana.csv", "skk-keyword-alpha.txt", true)