root/lang/ruby/aqtk-ruby/trunk/aqtk/ext/kakasi.c @ 31184

Revision 31184, 10.2 kB (checked in by winebarrel, 4 years ago)

support wakati gaki

  • Property svn:eol-style set to native
Line 
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
17extern VALUE rb_mAquesTalk;
18VALUE rb_cAquesTalk_Kakasi;
19static VALUE rb_eAquesTalk_Kakasi_Error;
20
21static 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
170static VALUE rb_aqtk_kakasi_convert_charcode(VALUE self, VALUE v_str) {
171  return rb_funcall(v_str, rb_intern("tosjis"), 0);
172}
173
174static 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
200static 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
249static 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
271static 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
285static 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
290static 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
299void 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
313BOOL 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}
Note: See TracBrowser for help on using the browser.