1 #include <gtk/gtk.h> // -*- tab-width:2 coding: viscii mode: c++ -*-
13 class MyText
: public Text
16 MyText(VSpell
* vs
):Text(vs
) {}
21 virtual bool ui_syllable_check();
22 virtual bool ui_word_check();
24 void show_wrong_syllables(unsigned p
);
26 void show_wrong_words(unsigned p
);
28 void iter_at(GtkTextIter
&iter
,int pos
);
29 string
word_to_utf8(unsigned seg_id
);
32 class MyTextFactory
: public TextFactory
35 Text
* create(VSpell
*vs
) const {
36 return new MyText(vs
);
40 static GtkTextTagTable
*tagtable_main
;
41 static GtkTextBuffer
*textbuffer_main
;
42 static GtkWidget
*textview_main
;
43 static GtkWidget
*log_main
;
44 static GtkWidget
*spell_entry
;
45 static GtkWidget
*ignore_button
,*ignore_all_button
,*spell_button
,*open_button
;
46 static GtkListStore
*list_store
;
47 static MyTextFactory myfactory
;
48 static VSpell
vspell(myfactory
);
49 static bool word_boundaries
;
51 static void text_reset(GtkTextBuffer
*textbuffer_main
)
53 GtkTextIter start
,end
;
54 gtk_text_buffer_get_start_iter(textbuffer_main
,&start
);
55 gtk_text_buffer_get_end_iter(textbuffer_main
,&end
);
56 gtk_text_buffer_remove_all_tags (textbuffer_main
, &start
,&end
);
59 void MyText::iter_at(GtkTextIter
&iter
,int pos
)
61 gtk_text_buffer_get_iter_at_offset(textbuffer_main
,&iter
,offset
+pos
);
64 void MyText::show_wrong_syllables(unsigned p
)
66 Suggestions
&sugg
= suggestions
;
67 int cc
,ii
,nn
,i
,n
= sugg
.size();
68 gtk_text_buffer_set_text (textbuffer_main
,
69 vspell
->get_utf8_text().c_str(),
70 strlen(vspell
->get_utf8_text().c_str()));
71 GtkTextIter start
,end
;
74 gtk_text_buffer_apply_tag_by_name(textbuffer_main
,
75 "bg-syllable", &start
, &end
);
76 for (i
= 0;i
< n
;i
++) {
78 int from
= st
[id
].start
;
79 int len
= strlen(get_sarch()[st
[id
].id
]);
80 printf("Syllable Mispelled: %d (%s) at %d\n",
81 id
,get_sarch()[st
[id
].id
],from
);
83 iter_at(end
,from
+len
);
84 gtk_text_buffer_apply_tag_by_name (textbuffer_main
,
85 (i
== p
? "mispelled" : "mispelled2"),
90 void MyText::show_words()
93 GtkTextIter start
,end
;
97 for (i
= 0;i
< n
;i
++) {
98 nn
= seg
[i
].node
.node
->get_syllable_count();
99 if (nn
== 1 && !word_boundaries
) {
103 int from
= st
[cc
].start
;
104 int to
= st
[cc
+nn
-1].start
+strlen(get_sarch()[st
[cc
+nn
-1].id
]);
105 printf("From %d to %d(%d)\n",from
,to
,n
);
108 gtk_text_buffer_apply_tag_by_name (textbuffer_main
, "word",
114 void MyText::show_wrong_words(unsigned p
)
117 GtkTextIter start
,end
;
119 Suggestions
&sugg
= suggestions
;
120 gtk_text_buffer_set_text (textbuffer_main
,
121 vspell
->get_utf8_text().c_str(),
122 strlen(vspell
->get_utf8_text().c_str()));
125 gtk_text_buffer_apply_tag_by_name(textbuffer_main
,
126 "bg-word", &start
, &end
);
130 for (i
= 0;i
< n
;i
++) {
132 for (cc
= ii
= 0;ii
< id
;ii
++)
133 cc
+= seg
[ii
].node
.node
->get_syllable_count();
135 nn
= seg
[id
].node
.node
->get_syllable_count();
137 int from
= st
[cc
].start
;
138 int to
= st
[cc
+nn
-1].start
+strlen(get_sarch()[st
[cc
+nn
-1].id
]);
139 printf("Mispelled at %d\n",id
);
142 gtk_text_buffer_apply_tag_by_name (textbuffer_main
,
143 (i
== p
? "mispelled" : "mispelled2"),
148 static void button_reset_callback (GtkWidget
*button
, gpointer data
)
150 text_reset(textbuffer_main
);
153 static bool is_checking
= true;
154 static bool ignore
= false;
155 static bool ignore_all
= false;
156 static bool processed
= false;
158 static void set_state(bool spellcheck
)
160 GtkTextIter start
,end
;
162 if (spellcheck
== is_checking
)
165 is_checking
= spellcheck
;
166 if (is_checking
|| !word_boundaries
) {
167 gtk_text_buffer_get_start_iter(textbuffer_main
,&start
);
168 gtk_text_buffer_get_end_iter(textbuffer_main
,&end
);
169 gtk_text_buffer_remove_all_tags (textbuffer_main
, &start
,&end
);
172 gtk_text_view_set_editable(GTK_TEXT_VIEW(textview_main
),!is_checking
);
173 gtk_widget_set_sensitive(GTK_WIDGET(open_button
),!is_checking
);
174 gtk_widget_set_sensitive(GTK_WIDGET(spell_button
),!is_checking
);
175 gtk_widget_set_sensitive(GTK_WIDGET(ignore_button
),is_checking
);
176 gtk_widget_set_sensitive(GTK_WIDGET(ignore_all_button
),is_checking
);
180 static void button_spell_callback (GtkWidget
*button
, gpointer data
)
182 GtkTextIter start
,end
;
186 gtk_text_buffer_get_start_iter(textbuffer_main
,&start
);
187 gtk_text_buffer_get_end_iter(textbuffer_main
,&end
);
189 gchar
*buffer
= gtk_text_buffer_get_text(textbuffer_main
,&start
,&end
,FALSE
);
190 //int len = g_utf8_strlen(buffer,-1);
192 vspell
.check(buffer
);
194 if (!word_boundaries
)
195 gtk_text_buffer_set_text (textbuffer_main
, vspell
.get_utf8_text().c_str(),strlen(vspell
.get_utf8_text().c_str()));
199 static void button_ignore_all_callback(GtkWidget
*button
,gpointer data
)
205 static void button_spell_accept_callback (GtkWidget
*button
, gpointer data
)
210 static void spell_entry_activate_callback(GtkEntry
*entry
, gpointer data
)
212 button_spell_accept_callback(NULL
,NULL
);
215 static void button_ignore_callback (GtkWidget
*button
, gpointer data
)
220 static void button_exit_callback (GtkWidget
*button
, gpointer data
)
225 static void window_destroy_callback (GtkObject
*object
,
231 static void button_search_callback(GtkWidget
*button
, gpointer data
);
234 candidates_row_activated (GtkTreeView
*treeview
,
236 GtkTreeViewColumn
*arg2
,
241 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store
),&iter
,path
))
243 gtk_tree_model_get(GTK_TREE_MODEL(list_store
),&iter
,0,&s
,-1);
244 gtk_entry_set_text(GTK_ENTRY(spell_entry
),s
);
247 void strict_spelling_checking_cb(GtkToggleButton
*b
,VSpell
*vspell
)
249 bool state
= gtk_toggle_button_get_active(b
);
250 vspell
->set_strict_word_checking(state
);
251 //gtk_toggle_button_set_active(b,state);
254 void length_normalization_cb(GtkToggleButton
*b
,VSpell
*vspell
)
256 bool state
= gtk_toggle_button_get_active(b
);
257 vspell
->set_normalization(state
);
258 //gtk_toggle_button_set_active(b,state);
261 void penalty_modification_cb(GtkEntry
*b
,VSpell
*vspell
)
263 const char *s
= gtk_entry_get_text(b
);
265 if (sscanf(s
,"%f",&val
) == 1)
266 vspell
->set_penalty(val
);
269 void penalty2_modification_cb(GtkEntry
*b
,VSpell
*vspell
)
271 const char *s
= gtk_entry_get_text(b
);
273 if (sscanf(s
,"%f",&val
) == 1)
274 vspell
->set_penalty2(val
);
277 void trigram_cb(GtkToggleButton
*b
,VSpell
*vspell
)
279 bool state
= gtk_toggle_button_get_active(b
);
280 vspell
->set_trigram(state
);
281 //gtk_toggle_button_set_active(b,state);
284 void word_boundaries_cb(GtkToggleButton
*b
,VSpell
*vspell
)
286 word_boundaries
= gtk_toggle_button_get_active(b
);
287 //gtk_toggle_button_set_active(b,state);
290 int main(int argc
,char **argv
)
292 gtk_init(&argc
,&argv
);
297 vspell
.set_penalty(0.9);
298 vspell
.set_penalty2(0.1);
299 vspell
.set_normalization(true);
300 vspell
.set_trigram(true);
301 word_boundaries
= true;
303 GtkWidget
*window_main
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
304 gtk_container_set_border_width(GTK_CONTAINER(window_main
),10);
305 gtk_window_set_default_size(GTK_WINDOW(window_main
),400,200);
306 g_signal_connect(window_main
,"destroy",G_CALLBACK(window_destroy_callback
),NULL
);
308 GtkWidget
*notebook
= gtk_notebook_new();
309 GtkWidget
*page1
,*page2
;
310 gtk_container_add(GTK_CONTAINER(window_main
),notebook
);
312 GtkWidget
*vbox_main
= gtk_vbox_new(FALSE
,10);
314 gtk_container_set_border_width(GTK_CONTAINER(page1
),10);
315 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),page1
,gtk_label_new("Main"));
319 GtkWidget *hbox_search = gtk_hbox_new(FALSE,10);
320 gtk_box_pack_start(GTK_BOX(vbox_main),hbox_search,FALSE,TRUE,0);
322 GtkWidget *entry_search = gtk_entry_new();
323 gtk_box_pack_start(GTK_BOX(hbox_search),entry_search,TRUE,TRUE,0);
324 GtkWidget *button_search = gtk_button_new_with_mnemonic("_Search");
325 g_signal_connect(button_search,"clicked",
326 G_CALLBACK(button_search_callback),entry_search);
327 gtk_box_pack_start(GTK_BOX(hbox_search),button_search,FALSE,TRUE,0);
329 log_main = gtk_label_new("");
330 gtk_label_set_line_wrap(GTK_LABEL(log_main),true);
331 gtk_box_pack_start(GTK_BOX(vbox_main),log_main,FALSE,FALSE,0);
334 // Text box+Spell box
335 GtkWidget
*paned
= gtk_hpaned_new();
336 gtk_paned_set_position(GTK_PANED(paned
),300);
337 gtk_box_pack_start(GTK_BOX(vbox_main
),paned
,TRUE
,TRUE
,0);
340 GtkWidget
*scrolled_window
= gtk_scrolled_window_new(NULL
,NULL
);
341 gtk_paned_add1(GTK_PANED(paned
),scrolled_window
);
343 tagtable_main
= gtk_text_tag_table_new();
344 textbuffer_main
= gtk_text_buffer_new(tagtable_main
);
345 gtk_text_buffer_create_tag (textbuffer_main
, "mispelled",
346 "weight", PANGO_WEIGHT_BOLD
,
347 "style", PANGO_STYLE_ITALIC
,
350 gtk_text_buffer_create_tag (textbuffer_main
, "mispelled2",
351 "weight", PANGO_WEIGHT_BOLD
,
352 "style", PANGO_STYLE_ITALIC
,
354 gtk_text_buffer_create_tag (textbuffer_main
, "word",
355 "underline", (gboolean
)TRUE
,
357 gtk_text_buffer_create_tag (textbuffer_main
, "bg-word",
358 "background", "grey",
360 gtk_text_buffer_create_tag (textbuffer_main
, "bg-syllable",
361 "background", "lightgrey",
364 textview_main
= gtk_text_view_new_with_buffer(textbuffer_main
);
365 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview_main
),GTK_WRAP_WORD
);
366 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window
),textview_main
);
369 GtkWidget
*spell_vbox
= gtk_vbox_new(FALSE
,10);
370 gtk_paned_add2(GTK_PANED(paned
),spell_vbox
);
372 GtkWidget
*spell_entry_hbox
= gtk_hbox_new(FALSE
,5);
373 gtk_box_pack_start(GTK_BOX(spell_vbox
),spell_entry_hbox
,FALSE
,FALSE
,0);
375 spell_entry
= gtk_entry_new();
376 g_signal_connect(G_OBJECT(spell_entry
),"activate",G_CALLBACK(spell_entry_activate_callback
),NULL
);
377 gtk_box_pack_start(GTK_BOX(spell_entry_hbox
),spell_entry
,TRUE
,TRUE
,0);
379 GtkWidget
*spell_entry_button
= gtk_button_new();
380 GtkWidget
*spell_entry_button_image
= gtk_image_new_from_stock(GTK_STOCK_OK
,GTK_ICON_SIZE_BUTTON
);
381 g_signal_connect(spell_entry_button
,"clicked",G_CALLBACK(button_spell_accept_callback
),NULL
);
382 gtk_container_add(GTK_CONTAINER(spell_entry_button
),spell_entry_button_image
);
383 gtk_box_pack_start(GTK_BOX(spell_entry_hbox
),spell_entry_button
,FALSE
,FALSE
,0);
385 GtkWidget
*view
= gtk_scrolled_window_new(NULL
,NULL
);
386 gtk_box_pack_start(GTK_BOX(spell_vbox
),view
,TRUE
,TRUE
,0);
388 GtkWidget
*w
= gtk_tree_view_new();
389 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(view
),w
);
390 list_store
= gtk_list_store_new(1,G_TYPE_STRING
);
391 gtk_tree_view_set_model(GTK_TREE_VIEW(w
),GTK_TREE_MODEL(list_store
));
392 gtk_tree_view_append_column(GTK_TREE_VIEW(w
),
393 gtk_tree_view_column_new_with_attributes("Candidates",
394 gtk_cell_renderer_text_new(),
398 g_signal_connect(G_OBJECT(w
),"row-activated",
399 G_CALLBACK(candidates_row_activated
),
403 GtkWidget
*hbox_command
= gtk_hbox_new(TRUE
,10);
404 gtk_box_pack_start(GTK_BOX(vbox_main
),hbox_command
,FALSE
,TRUE
,0);
406 open_button
= gtk_button_new_with_mnemonic("_Open");
407 //g_signal_connect(button_spell,"clicked",G_CALLBACK(button_spell_callback),NULL);
408 gtk_box_pack_start(GTK_BOX(hbox_command
),open_button
,FALSE
,TRUE
,0);
409 spell_button
= gtk_button_new_with_mnemonic("_Check");
410 g_signal_connect(spell_button
,"clicked",G_CALLBACK(button_spell_callback
),NULL
);
411 gtk_box_pack_start(GTK_BOX(hbox_command
),spell_button
,FALSE
,TRUE
,0);
412 //GtkWidget *button_reset = gtk_button_new_with_mnemonic("_Reset");
413 //g_signal_connect(button_reset,"clicked",G_CALLBACK(button_reset_callback),NULL);
414 //gtk_box_pack_start(GTK_BOX(hbox_command),button_reset,FALSE,TRUE,0);
415 ignore_button
= gtk_button_new_with_mnemonic("_Ignore");
416 g_signal_connect(ignore_button
,"clicked",G_CALLBACK(button_ignore_callback
),NULL
);
417 gtk_box_pack_start(GTK_BOX(hbox_command
),ignore_button
,FALSE
,TRUE
,0);
418 ignore_all_button
= gtk_button_new_with_mnemonic("Ignore _All");
419 g_signal_connect(ignore_all_button
,"clicked",G_CALLBACK(button_ignore_all_callback
),NULL
);
420 gtk_box_pack_start(GTK_BOX(hbox_command
),ignore_all_button
,FALSE
,TRUE
,0);
421 GtkWidget
*button_exit
= gtk_button_new_with_mnemonic("_Exit");
422 g_signal_connect(button_exit
,"clicked",G_CALLBACK(button_exit_callback
),NULL
);
423 gtk_box_pack_start(GTK_BOX(hbox_command
),button_exit
,FALSE
,TRUE
,0);
425 vbox_main
= gtk_vbox_new(FALSE
,10);
427 gtk_container_set_border_width(GTK_CONTAINER(page2
),10);
428 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),page2
,gtk_label_new("Settings"));
429 w
= gtk_check_button_new_with_label("Strict spelling checking");
430 gtk_box_pack_start(GTK_BOX(vbox_main
),w
,FALSE
,FALSE
,0);
431 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w
),vspell
.get_strict_word_checking());
432 g_signal_connect(G_OBJECT(w
),"toggled",G_CALLBACK(strict_spelling_checking_cb
),&vspell
);
434 w
= gtk_check_button_new_with_label("Length normalization");
435 gtk_box_pack_start(GTK_BOX(vbox_main
),w
,FALSE
,FALSE
,0);
436 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w
),vspell
.get_normalization());
437 g_signal_connect(G_OBJECT(w
),"toggled",G_CALLBACK(length_normalization_cb
),&vspell
);
439 w
= gtk_check_button_new_with_label("Trigram");
440 gtk_box_pack_start(GTK_BOX(vbox_main
),w
,FALSE
,FALSE
,0);
441 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w
),vspell
.get_trigram());
442 g_signal_connect(G_OBJECT(w
),"toggled",G_CALLBACK(trigram_cb
),&vspell
);
444 w
= gtk_check_button_new_with_label("Show word boundaries");
445 gtk_box_pack_start(GTK_BOX(vbox_main
),w
,FALSE
,FALSE
,0);
446 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w
),word_boundaries
);
447 g_signal_connect(G_OBJECT(w
),"toggled",G_CALLBACK(word_boundaries_cb
),&vspell
);
449 GtkWidget
*hbox
= gtk_hbox_new(FALSE
,10);
450 gtk_box_pack_start(GTK_BOX(vbox_main
),hbox
,FALSE
,FALSE
,0);
451 gtk_box_pack_start(GTK_BOX(hbox
),gtk_label_new("Penalty"),FALSE
,FALSE
,0);
453 gtk_box_pack_start(GTK_BOX(hbox
),w
,FALSE
,FALSE
,0);
455 sprintf(buff
,"%f",vspell
.get_penalty());
456 gtk_entry_set_text(GTK_ENTRY(w
),buff
);
457 g_signal_connect(G_OBJECT(w
),"changed",G_CALLBACK(penalty_modification_cb
),&vspell
);
459 hbox
= gtk_hbox_new(FALSE
,10);
460 gtk_box_pack_start(GTK_BOX(vbox_main
),hbox
,FALSE
,FALSE
,0);
461 gtk_box_pack_start(GTK_BOX(hbox
),gtk_label_new("Penalty2"),FALSE
,FALSE
,0);
463 gtk_box_pack_start(GTK_BOX(hbox
),w
,FALSE
,FALSE
,0);
464 sprintf(buff
,"%f",vspell
.get_penalty2());
465 gtk_entry_set_text(GTK_ENTRY(w
),buff
);
466 g_signal_connect(G_OBJECT(w
),"changed",G_CALLBACK(penalty2_modification_cb
),&vspell
);
470 gtk_widget_show_all(window_main
);
474 void button_search_callback(GtkWidget
*button
, gpointer data
)
476 GtkWidget
*entry_search
= GTK_WIDGET(data
);
477 const char *text
= gtk_entry_get_text(GTK_ENTRY(data
));
479 string
is(viet_to_viscii(text
));
483 while (p
< is
.size()) {
484 int pp
= is
.find(' ',p
);
485 if (pp
== string::npos
)
487 s
= is
.substr(p
,pp
-p
);
489 strid id
= get_sarch()[s
];
490 if (!get_sarch().in_dict(id
)) {
491 char *str
= g_strdup_printf("%s not found",viet_to_utf8(s
.c_str()));
492 gtk_label_set_text(GTK_LABEL(log_main
),str
);
501 ptr = get_root()->follow_syllables(ids);
503 char *str = g_strdup_printf("Word %s found with prob %.02f.",text,ptr->get_prob());
504 gtk_label_set_text(GTK_LABEL(log_main),str);
507 gtk_label_set_text(GTK_LABEL(log_main),"Word not found.");
511 void candidates_reset()
513 gtk_list_store_clear(list_store
);
516 void candidates_add(const gchar
*s
)
519 gtk_list_store_append(list_store
,&iter
);
520 gtk_list_store_set(list_store
,&iter
,
525 bool MyText::ui_syllable_check()
527 unsigned i
,n
= suggestions
.size();
528 for (i
= 0;i
< n
;i
++) {
529 show_wrong_syllables(i
);
532 from
= st
[suggestions
[i
].id
].start
;
533 len
= strlen(get_sarch()[st
[suggestions
[i
].id
].id
]);
534 string s
= substr(from
,len
);
535 gtk_entry_set_text(GTK_ENTRY(spell_entry
),s
.c_str());
536 vector
<string
> candidates
;
539 get_syllable_candidates(get_sarch()[st
[suggestions
[i
].id
].id
],c
);
540 c
.get_list(candidates
);
541 vector
<string
>::iterator iter
;
542 for (iter
= candidates
.begin();iter
!= candidates
.end();++ iter
)
543 candidates_add(viet_to_utf8(iter
->c_str()));
544 processed
= ignore_all
= ignore
= false;
545 while (!gtk_main_iteration() && !ignore
&& !ignore_all
&& !processed
);
551 return true; // force to exit
554 cerr
<< "Input: The right one is:" << endl
;
556 const gchar
*s
= gtk_entry_get_text(GTK_ENTRY(spell_entry
));
559 continue; // i don't accept an empty string
561 replace(st
[suggestions
[i
].id
].start
, // from
562 strlen(get_sarch()[st
[suggestions
[i
].id
].get_id()]), // size
564 vspell
->add(get_sarch()[viet_to_viscii_force(s
)]);
568 return true; // some things went wrong
573 string
MyText::word_to_utf8(unsigned seg_id
)
577 seg
[seg_id
].node
->get_syllables(sylls
);
578 int i
,n
= sylls
.size();
579 for (i
= 0;i
< n
;i
++) {
583 syll
.parse(get_sarch()[sylls
[i
]]);
584 s
+= viet_to_utf8(syll
.to_str().c_str());
589 bool MyText::ui_word_check()
591 unsigned i
,n
= suggestions
.size();
594 for (i
= 0;i
< n
;i
++) {
597 count
= seg
[suggestions
[i
].id
].node
->get_syllable_count();
598 pos
= (*seg
.we
)[seg
[suggestions
[i
].id
].id
].pos
;
601 from
= st
[pos
].start
;
602 len
= st
[pos2
].start
+strlen(get_sarch()[st
[pos2
].id
])-from
;
603 string s
= substr(from
,len
);
604 gtk_entry_set_text(GTK_ENTRY(spell_entry
),s
.c_str());
606 candidates_add(word_to_utf8(suggestions
[i
].id
).c_str());
607 processed
= ignore_all
= ignore
= false;
608 while (!gtk_main_iteration() && !ignore
&& !ignore_all
&& !processed
);
614 return true; // force to exit
617 string s
= gtk_entry_get_text(GTK_ENTRY(spell_entry
));
622 count
= seg
[suggestions
[i
].id
].node
->get_syllable_count();
623 pos
= (*seg
.we
)[seg
[suggestions
[i
].id
].id
].pos
;
627 vector
<unsigned> separators
;
628 while ((p
= s
.find('|')) != string::npos
) {
629 separators
.push_back(st
[pos
].start
+g_utf8_strlen(s
.substr(0,p
).c_str(),-1)+offset
);
633 replace(st
[pos
].start
, // from
634 st
[pos2
].start
+strlen(get_sarch()[st
[pos2
].get_id()])-st
[pos
].start
, // size
637 // add separators after replacing the text, to have old separators removed
638 vspell
->add_word(viet_to_viscii_force(s
.c_str()));
639 vspell
->add_separators(separators
);
640 return false; // continue checking
642 return true; // some things went wrong
647 bool MyText::word_check()
649 bool ret
= Text::word_check();