| 1 | #include <windows.h> |
|---|
| 2 | #include <string.h> |
|---|
| 3 | |
|---|
| 4 | #include "libkakasi.h" |
|---|
| 5 | #include "dictionary.h" |
|---|
| 6 | |
|---|
| 7 | #include "ruby.h" |
|---|
| 8 | #include "aqtk_internal.h" |
|---|
| 9 | |
|---|
| 10 | #define KAKASI_DEFAULT_OPT "-JH -KH" |
|---|
| 11 | #define KAKASI_OPT_DELIM " \t" |
|---|
| 12 | #define ACCEPT_CHARACTER "',./;�A�B�H�[��������������������������������������������������������������������ĂłƂǂȂɂʂ˂̂͂ςЂт҂ӂԂՂւׂقڂۂ܂݂ނ߂���������������3456789" |
|---|
| 13 | #define UNACCEPTABLE "�A" |
|---|
| 14 | |
|---|
| 15 | #define HASH_ASET_STR(h, k, v) rb_hash_aset(h, rb_str_new2(k), rb_str_new2(v)) |
|---|
| 16 | |
|---|
| 17 | extern VALUE rb_mAquesTalk; |
|---|
| 18 | VALUE rb_cAquesTalk_Kakasi; |
|---|
| 19 | static VALUE rb_eAquesTalk_Kakasi_Error; |
|---|
| 20 | |
|---|
| 21 | static VALUE rb_aqtk_kakasi_initialize(int argc, VALUE *argv, VALUE self) { |
|---|
| 22 | VALUE v_opt, v_table; |
|---|
| 23 | |
|---|
| 24 | rb_scan_args(argc, argv, "01", &v_opt); |
|---|
| 25 | |
|---|
| 26 | if (NIL_P(v_opt)) { |
|---|
| 27 | v_opt = rb_str_new2(KAKASI_DEFAULT_OPT); |
|---|
| 28 | } else { |
|---|
| 29 | Check_Type(v_opt, T_STRING); |
|---|
| 30 | } |
|---|
| 31 | |
|---|
| 32 | rb_iv_set(self, "@opt", v_opt); |
|---|
| 33 | |
|---|
| 34 | rb_iv_set(self, "@accept", rb_str_new2(ACCEPT_CHARACTER)); |
|---|
| 35 | |
|---|
| 36 | v_table = rb_hash_new(); |
|---|
| 37 | |
|---|
| 38 | HASH_ASET_STR(v_table, "��", "��"); |
|---|
| 39 | HASH_ASET_STR(v_table, "��", "��"); |
|---|
| 40 | HASH_ASET_STR(v_table, "��", "��"); |
|---|
| 41 | HASH_ASET_STR(v_table, "��", "��"); |
|---|
| 42 | HASH_ASET_STR(v_table, "��", "��"); |
|---|
| 43 | |
|---|
| 44 | HASH_ASET_STR(v_table, "A", "���["); |
|---|
| 45 | HASH_ASET_STR(v_table, "B", "�с["); |
|---|
| 46 | HASH_ASET_STR(v_table, "C", "���["); |
|---|
| 47 | HASH_ASET_STR(v_table, "D", "�ł��["); |
|---|
| 48 | HASH_ASET_STR(v_table, "E", "���["); |
|---|
| 49 | HASH_ASET_STR(v_table, "F", "����); |
|---|
| 50 | HASH_ASET_STR(v_table, "G", "���["); |
|---|
| 51 | HASH_ASET_STR(v_table, "H", "������"); |
|---|
| 52 | HASH_ASET_STR(v_table, "I", "����"); |
|---|
| 53 | HASH_ASET_STR(v_table, "J", "������"); |
|---|
| 54 | HASH_ASET_STR(v_table, "K", "����"); |
|---|
| 55 | HASH_ASET_STR(v_table, "L", "����; |
|---|
| 56 | HASH_ASET_STR(v_table, "M", "����); |
|---|
| 57 | HASH_ASET_STR(v_table, "N", "����); |
|---|
| 58 | HASH_ASET_STR(v_table, "O", "���["); |
|---|
| 59 | HASH_ASET_STR(v_table, "P", "�ҁ["); |
|---|
| 60 | HASH_ASET_STR(v_table, "Q", "����"); |
|---|
| 61 | HASH_ASET_STR(v_table, "R", "���[��; |
|---|
| 62 | HASH_ASET_STR(v_table, "S", "����"); |
|---|
| 63 | HASH_ASET_STR(v_table, "T", "���["); |
|---|
| 64 | HASH_ASET_STR(v_table, "U", "��"); |
|---|
| 65 | HASH_ASET_STR(v_table, "V", "�Ԃ�"); |
|---|
| 66 | HASH_ASET_STR(v_table, "W", "���Ԃ��["); |
|---|
| 67 | HASH_ASET_STR(v_table, "X", "�������"); |
|---|
| 68 | HASH_ASET_STR(v_table, "Y", "�킢"); |
|---|
| 69 | HASH_ASET_STR(v_table, "Z", "�����); |
|---|
| 70 | |
|---|
| 71 | HASH_ASET_STR(v_table, "a", "���["); |
|---|
| 72 | HASH_ASET_STR(v_table, "b", "�с["); |
|---|
| 73 | HASH_ASET_STR(v_table, "c", "���["); |
|---|
| 74 | HASH_ASET_STR(v_table, "d", "�ł��["); |
|---|
| 75 | HASH_ASET_STR(v_table, "e", "���["); |
|---|
| 76 | HASH_ASET_STR(v_table, "f", "����); |
|---|
| 77 | HASH_ASET_STR(v_table, "g", "���["); |
|---|
| 78 | HASH_ASET_STR(v_table, "h", "������"); |
|---|
| 79 | HASH_ASET_STR(v_table, "i", "����"); |
|---|
| 80 | HASH_ASET_STR(v_table, "j", "������"); |
|---|
| 81 | HASH_ASET_STR(v_table, "k", "����"); |
|---|
| 82 | HASH_ASET_STR(v_table, "l", "����; |
|---|
| 83 | HASH_ASET_STR(v_table, "m", "����); |
|---|
| 84 | HASH_ASET_STR(v_table, "n", "����); |
|---|
| 85 | HASH_ASET_STR(v_table, "o", "���["); |
|---|
| 86 | HASH_ASET_STR(v_table, "p", "�ҁ["); |
|---|
| 87 | HASH_ASET_STR(v_table, "q", "����"); |
|---|
| 88 | HASH_ASET_STR(v_table, "r", "���[��; |
|---|
| 89 | HASH_ASET_STR(v_table, "s", "����"); |
|---|
| 90 | HASH_ASET_STR(v_table, "t", "���["); |
|---|
| 91 | HASH_ASET_STR(v_table, "u", "��"); |
|---|
| 92 | HASH_ASET_STR(v_table, "v", "�Ԃ�"); |
|---|
| 93 | HASH_ASET_STR(v_table, "w", "���Ԃ��["); |
|---|
| 94 | HASH_ASET_STR(v_table, "x", "�������"); |
|---|
| 95 | HASH_ASET_STR(v_table, "y", "�킢"); |
|---|
| 96 | HASH_ASET_STR(v_table, "z", "�����); |
|---|
| 97 | |
|---|
| 98 | HASH_ASET_STR(v_table, "�`", "���["); |
|---|
| 99 | HASH_ASET_STR(v_table, "�a", "�с["); |
|---|
| 100 | HASH_ASET_STR(v_table, "�b", "���["); |
|---|
| 101 | HASH_ASET_STR(v_table, "�c", "�ł��["); |
|---|
| 102 | HASH_ASET_STR(v_table, "�d", "���["); |
|---|
| 103 | HASH_ASET_STR(v_table, "�e", "����); |
|---|
| 104 | HASH_ASET_STR(v_table, "�f", "���["); |
|---|
| 105 | HASH_ASET_STR(v_table, "�g", "������"); |
|---|
| 106 | HASH_ASET_STR(v_table, "�h", "����"); |
|---|
| 107 | HASH_ASET_STR(v_table, "�i", "������"); |
|---|
| 108 | HASH_ASET_STR(v_table, "�j", "����"); |
|---|
| 109 | HASH_ASET_STR(v_table, "�k", "����; |
|---|
| 110 | HASH_ASET_STR(v_table, "�l", "����); |
|---|
| 111 | HASH_ASET_STR(v_table, "�m", "����); |
|---|
| 112 | HASH_ASET_STR(v_table, "�n", "���["); |
|---|
| 113 | HASH_ASET_STR(v_table, "�o", "�ҁ["); |
|---|
| 114 | HASH_ASET_STR(v_table, "�p", "����"); |
|---|
| 115 | HASH_ASET_STR(v_table, "�q", "���[��; |
|---|
| 116 | HASH_ASET_STR(v_table, "�r", "����"); |
|---|
| 117 | HASH_ASET_STR(v_table, "�s", "���["); |
|---|
| 118 | HASH_ASET_STR(v_table, "�t", "��"); |
|---|
| 119 | HASH_ASET_STR(v_table, "�u", "�Ԃ�"); |
|---|
| 120 | HASH_ASET_STR(v_table, "�v", "���Ԃ��["); |
|---|
| 121 | HASH_ASET_STR(v_table, "�w", "�������"); |
|---|
| 122 | HASH_ASET_STR(v_table, "�x", "�킢"); |
|---|
| 123 | HASH_ASET_STR(v_table, "�y", "�����); |
|---|
| 124 | |
|---|
| 125 | HASH_ASET_STR(v_table, "��", "���["); |
|---|
| 126 | HASH_ASET_STR(v_table, "��", "�с["); |
|---|
| 127 | HASH_ASET_STR(v_table, "��", "���["); |
|---|
| 128 | HASH_ASET_STR(v_table, "��", "�ł��["); |
|---|
| 129 | HASH_ASET_STR(v_table, "��", "���["); |
|---|
| 130 | HASH_ASET_STR(v_table, "��", "����); |
|---|
| 131 | HASH_ASET_STR(v_table, "��", "���["); |
|---|
| 132 | HASH_ASET_STR(v_table, "��", "������"); |
|---|
| 133 | HASH_ASET_STR(v_table, "��", "����"); |
|---|
| 134 | HASH_ASET_STR(v_table, "��", "������"); |
|---|
| 135 | HASH_ASET_STR(v_table, "��", "����"); |
|---|
| 136 | HASH_ASET_STR(v_table, "��", "����; |
|---|
| 137 | HASH_ASET_STR(v_table, "��", "����); |
|---|
| 138 | HASH_ASET_STR(v_table, "��", "����); |
|---|
| 139 | HASH_ASET_STR(v_table, "��", "���["); |
|---|
| 140 | HASH_ASET_STR(v_table, "��", "�ҁ["); |
|---|
| 141 | HASH_ASET_STR(v_table, "��", "����"); |
|---|
| 142 | HASH_ASET_STR(v_table, "��", "���[��; |
|---|
| 143 | HASH_ASET_STR(v_table, "��", "����"); |
|---|
| 144 | HASH_ASET_STR(v_table, "��", "���["); |
|---|
| 145 | HASH_ASET_STR(v_table, "��", "��"); |
|---|
| 146 | HASH_ASET_STR(v_table, "��", "�Ԃ�"); |
|---|
| 147 | HASH_ASET_STR(v_table, "��", "���Ԃ��["); |
|---|
| 148 | HASH_ASET_STR(v_table, "��", "�������"); |
|---|
| 149 | HASH_ASET_STR(v_table, "��", "�킢"); |
|---|
| 150 | HASH_ASET_STR(v_table, "��", "�����); |
|---|
| 151 | |
|---|
| 152 | HASH_ASET_STR(v_table, "�O", "0"); |
|---|
| 153 | HASH_ASET_STR(v_table, "�P", "1"); |
|---|
| 154 | HASH_ASET_STR(v_table, "�Q", "2"); |
|---|
| 155 | HASH_ASET_STR(v_table, "�R", "3"); |
|---|
| 156 | HASH_ASET_STR(v_table, "�S", "4"); |
|---|
| 157 | HASH_ASET_STR(v_table, "�T", "5"); |
|---|
| 158 | HASH_ASET_STR(v_table, "�U", "6"); |
|---|
| 159 | HASH_ASET_STR(v_table, "�V", "7"); |
|---|
| 160 | HASH_ASET_STR(v_table, "�W", "8"); |
|---|
| 161 | HASH_ASET_STR(v_table, "�X", "9"); |
|---|
| 162 | |
|---|
| 163 | HASH_ASET_STR(v_table, "�`", "�["); |
|---|
| 164 | |
|---|
| 165 | rb_iv_set(self, "@table", v_table); |
|---|
| 166 | |
|---|
| 167 | return Qnil; |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | static VALUE rb_aqtk_kakasi_convert_charcode(VALUE self, VALUE v_str) { |
|---|
| 171 | return rb_funcall(v_str, rb_intern("tosjis"), 0); |
|---|
| 172 | } |
|---|
| 173 | |
|---|
| 174 | static VALUE rb_aqtk_kakasi_wakati(VALUE self, VALUE v_str) { |
|---|
| 175 | VALUE v_retval; |
|---|
| 176 | char *kakasi_argv[] = { "kakasi", "-w" }; |
|---|
| 177 | char *retval; |
|---|
| 178 | VALUE eval_argv[] = { rb_str_new2("gsub(/��\b/s, '��.gsub(' ', '')") }; |
|---|
| 179 | |
|---|
| 180 | Check_Type(v_str, T_STRING); |
|---|
| 181 | |
|---|
| 182 | if (kakasi_getopt_argv(2, kakasi_argv) != 0) { |
|---|
| 183 | kakasi_close_kanwadict(); |
|---|
| 184 | rb_raise(rb_eAquesTalk_Kakasi_Error, "Init kakasi failed"); |
|---|
| 185 | } |
|---|
| 186 | |
|---|
| 187 | retval = kakasi_do(RSTRING_PTR(v_str)); |
|---|
| 188 | v_retval = rb_str_buf_new2(retval); |
|---|
| 189 | |
|---|
| 190 | if (*retval) { |
|---|
| 191 | kakasi_free(retval); |
|---|
| 192 | } |
|---|
| 193 | |
|---|
| 194 | kakasi_close_kanwadict(); |
|---|
| 195 | v_retval = rb_obj_instance_eval(1, eval_argv, v_retval); |
|---|
| 196 | |
|---|
| 197 | return v_retval; |
|---|
| 198 | } |
|---|
| 199 | |
|---|
| 200 | static VALUE rb_aqtk_kakasi_kakasi(VALUE self, VALUE v_str) { |
|---|
| 201 | VALUE v_opt, v_retval; |
|---|
| 202 | int kakasi_argc = 0, optlen; |
|---|
| 203 | char **kakasi_argv, **kakasi_argv_p; |
|---|
| 204 | char *opt, *tok, *ctx, *retval; |
|---|
| 205 | |
|---|
| 206 | Check_Type(v_str, T_STRING); |
|---|
| 207 | v_opt = rb_iv_get(self, "@opt"); |
|---|
| 208 | optlen = RSTRING_LEN(v_opt); |
|---|
| 209 | |
|---|
| 210 | if (optlen < 1) { |
|---|
| 211 | return v_str; |
|---|
| 212 | } |
|---|
| 213 | |
|---|
| 214 | kakasi_argv = ALLOCA_N(char *, RSTRING_LEN(v_opt)); |
|---|
| 215 | kakasi_argv_p = kakasi_argv; |
|---|
| 216 | opt = ALLOCA_N(char, optlen + 1); |
|---|
| 217 | strcpy_s(opt, optlen + 1, RSTRING_PTR(v_opt)); |
|---|
| 218 | |
|---|
| 219 | *kakasi_argv_p = "kakasi"; |
|---|
| 220 | kakasi_argv_p++; |
|---|
| 221 | kakasi_argc++; |
|---|
| 222 | |
|---|
| 223 | tok = strtok_s(opt, KAKASI_OPT_DELIM, &ctx); |
|---|
| 224 | |
|---|
| 225 | while (tok != NULL) { |
|---|
| 226 | *kakasi_argv_p = tok; |
|---|
| 227 | kakasi_argv_p++; |
|---|
| 228 | kakasi_argc++; |
|---|
| 229 | tok = strtok_s(NULL, KAKASI_OPT_DELIM, &ctx); |
|---|
| 230 | } |
|---|
| 231 | |
|---|
| 232 | if (kakasi_getopt_argv(kakasi_argc, kakasi_argv) != 0) { |
|---|
| 233 | kakasi_close_kanwadict(); |
|---|
| 234 | rb_raise(rb_eAquesTalk_Kakasi_Error, "Init kakasi failed"); |
|---|
| 235 | } |
|---|
| 236 | |
|---|
| 237 | retval = kakasi_do(RSTRING_PTR(v_str)); |
|---|
| 238 | v_retval = rb_str_buf_new2(retval); |
|---|
| 239 | |
|---|
| 240 | if (*retval) { |
|---|
| 241 | kakasi_free(retval); |
|---|
| 242 | } |
|---|
| 243 | |
|---|
| 244 | kakasi_close_kanwadict(); |
|---|
| 245 | |
|---|
| 246 | return v_retval; |
|---|
| 247 | } |
|---|
| 248 | |
|---|
| 249 | static VALUE _normaliz_iter(VALUE i, VALUE *arg) { |
|---|
| 250 | VALUE v_accept, v_table, v_buf, v_char; |
|---|
| 251 | |
|---|
| 252 | v_accept = arg[0]; |
|---|
| 253 | v_table = arg[1]; |
|---|
| 254 | v_buf = arg[2]; |
|---|
| 255 | |
|---|
| 256 | v_char = rb_hash_aref(v_table, i); |
|---|
| 257 | |
|---|
| 258 | if (NIL_P(v_char) && rb_funcall(v_accept, rb_intern("include?"), 1, i) == Qtrue) { |
|---|
| 259 | v_char = i; |
|---|
| 260 | } |
|---|
| 261 | |
|---|
| 262 | if (!NIL_P(v_char)) { |
|---|
| 263 | rb_str_concat(v_buf, v_char); |
|---|
| 264 | } else { |
|---|
| 265 | rb_str_cat2(v_buf, UNACCEPTABLE); |
|---|
| 266 | } |
|---|
| 267 | |
|---|
| 268 | return Qnil; |
|---|
| 269 | } |
|---|
| 270 | |
|---|
| 271 | static VALUE rb_aqtk_kakasi_normalize(VALUE self, VALUE v_str) { |
|---|
| 272 | VALUE v_accept = rb_iv_get(self, "@accept"); |
|---|
| 273 | VALUE v_table = rb_iv_get(self, "@table"); |
|---|
| 274 | VALUE v_buf = rb_str_new("", 0); |
|---|
| 275 | VALUE iter_arg[3] = { v_accept, v_table, v_buf }; |
|---|
| 276 | VALUE eval_argv[] = { rb_str_new2("split(//s)") }; |
|---|
| 277 | VALUE v_chars = rb_obj_instance_eval(1, eval_argv, v_str); |
|---|
| 278 | |
|---|
| 279 | v_chars = rb_obj_instance_eval(1, eval_argv, v_str); |
|---|
| 280 | rb_iterate(rb_each, v_chars, _normaliz_iter, (VALUE) iter_arg); |
|---|
| 281 | |
|---|
| 282 | return v_buf; |
|---|
| 283 | } |
|---|
| 284 | |
|---|
| 285 | static VALUE rb_aqtk_kakasi_convert_number(VALUE self, VALUE v_str) { |
|---|
| 286 | VALUE eval_argv[] = { rb_str_new2("gsub(/\\d+/s) {|m| \"<NUM VAL=#{m}>\" }") }; |
|---|
| 287 | return rb_obj_instance_eval(1, eval_argv, v_str); |
|---|
| 288 | } |
|---|
| 289 | |
|---|
| 290 | static VALUE rb_aqtk_kakasi_filter(VALUE self, VALUE v_str) { |
|---|
| 291 | v_str = rb_funcall(self, rb_intern("convert_charcode"), 1, v_str); |
|---|
| 292 | v_str = rb_funcall(self, rb_intern("wakati"), 1, v_str); |
|---|
| 293 | v_str = rb_funcall(self, rb_intern("kakasi"), 1, v_str); |
|---|
| 294 | v_str = rb_funcall(self, rb_intern("normalize"), 1, v_str); |
|---|
| 295 | v_str = rb_funcall(self, rb_intern("convert_number"), 1, v_str); |
|---|
| 296 | return v_str; |
|---|
| 297 | } |
|---|
| 298 | |
|---|
| 299 | void Init_kakasi() { |
|---|
| 300 | rb_require("kconv"); |
|---|
| 301 | rb_cAquesTalk_Kakasi = rb_define_class_under(rb_mAquesTalk, "Kakasi", rb_cObject); |
|---|
| 302 | rb_eAquesTalk_Kakasi_Error = rb_define_class_under(rb_cAquesTalk_Kakasi, "Error", rb_eStandardError); |
|---|
| 303 | |
|---|
| 304 | rb_define_method(rb_cAquesTalk_Kakasi, "initialize", rb_aqtk_kakasi_initialize, -1); |
|---|
| 305 | rb_define_private_method(rb_cAquesTalk_Kakasi, "convert_charcode", rb_aqtk_kakasi_convert_charcode, 1); |
|---|
| 306 | rb_define_private_method(rb_cAquesTalk_Kakasi, "wakati", rb_aqtk_kakasi_wakati, 1); |
|---|
| 307 | rb_define_private_method(rb_cAquesTalk_Kakasi, "kakasi", rb_aqtk_kakasi_kakasi, 1); |
|---|
| 308 | rb_define_private_method(rb_cAquesTalk_Kakasi, "normalize", rb_aqtk_kakasi_normalize, 1); |
|---|
| 309 | rb_define_private_method(rb_cAquesTalk_Kakasi, "convert_number", rb_aqtk_kakasi_convert_number, 1); |
|---|
| 310 | rb_define_method(rb_cAquesTalk_Kakasi, "filter", rb_aqtk_kakasi_filter, 1); |
|---|
| 311 | } |
|---|
| 312 | |
|---|
| 313 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { |
|---|
| 314 | switch(fdwReason) { |
|---|
| 315 | case DLL_PROCESS_ATTACH: |
|---|
| 316 | kakasi_module(hinstDLL); |
|---|
| 317 | break; |
|---|
| 318 | case DLL_PROCESS_DETACH: |
|---|
| 319 | kakasi_unload_dict(); |
|---|
| 320 | break; |
|---|
| 321 | case DLL_THREAD_ATTACH: |
|---|
| 322 | break; |
|---|
| 323 | case DLL_THREAD_DETACH: |
|---|
| 324 | break; |
|---|
| 325 | } |
|---|
| 326 | |
|---|
| 327 | return TRUE; |
|---|
| 328 | } |
|---|