/** * Return a list of all misspelled words inside a given array of strings. * @param ary an array of strings to check for. * @return array of strings: words that are misspelled. */ static VALUE aspell_list_misspelled(VALUE self, VALUE ary) { VALUE result = rb_hash_new(); //create checker AspellSpeller *speller = get_speller(self); AspellDocumentChecker * checker = get_checker(speller); AspellToken token; VALUE word, vline; int count=RARRAY_LEN(ary); int c=0; //iterate over array while(c<count) { //process line vline = RARRAY_PTR(ary)[c]; aspell_document_checker_process(checker, STR2CSTR(vline), -1); //iterate over all misspelled words while (token = aspell_document_checker_next_misspelling(checker), token.len != 0) { //extract word by start/length qualifier word = rb_funcall(vline, rb_intern("[]"), 2, INT2FIX(token.offset), INT2FIX(token.len)); rb_hash_aset(result, word, Qnil); //yield block, if given if (rb_block_given_p()) rb_yield(word); } c++; } //free checker delete_aspell_document_checker(checker); result = rb_funcall(result, rb_intern("keys"), 0); return result; }
/** * This method will check an array of strings for misspelled words. * This method needs a block to work proper. Each misspelled word is yielded, * a correct word as result from the block is assumed. * Common use: * * a = Aspell.new(...) * text = ... * a.correct_lines(text) { |badword| * puts "Error: #{badword}\n" * puts a.suggest(badword).join(" | ") * gets #the input is returned as right word * } * * @param ary the array of strings to check. * @result an array holding all lines with corrected words. */ static VALUE aspell_correct_lines(VALUE self, VALUE ary) { VALUE result = ary; if (rb_block_given_p()) { //create checker AspellSpeller *speller = get_speller(self); AspellDocumentChecker * checker = get_checker(speller); AspellToken token; //some tmp values VALUE vline, sline; VALUE word, rword; char *line; int count=RARRAY_LEN(ary); int c=0; //create new result array result = rb_ary_new(); //iterate over array while(c<count) { int offset=0; //fetch line vline = RARRAY_PTR(ary)[c]; //save line sline = rb_funcall(vline, rb_intern("dup"), 0); //c representation line = STR2CSTR(vline); //process line aspell_document_checker_process(checker, line, -1); //iterate over all misspelled words while (token = aspell_document_checker_next_misspelling(checker), token.len != 0) { //extract word by start/length qualifier word = rb_funcall(vline, rb_intern("[]"), 2, INT2FIX(token.offset), INT2FIX(token.len)); //get the right word from the block rword = rb_yield(word); //nil -> do nothing if(rword == Qnil) continue; //check for string if (TYPE(rword) != T_STRING) rb_raise(cAspellError, "%s", "Need a String to substitute"); //chomp the string rb_funcall(rword, rb_intern("chomp!"), 0); //empty string -> do nothing if(strlen(STR2CSTR(rword)) == 0) continue; //remember word for later suggestion aspell_speller_store_replacement(speller, STR2CSTR(word), -1, STR2CSTR(rword), -1); //substitute the word by replacement rb_funcall(sline, rb_intern("[]="), 3, INT2FIX(token.offset+offset), INT2FIX(token.len), rword); //adjust offset offset += strlen(STR2CSTR(rword))-strlen(STR2CSTR(word)); //printf("replace >%s< with >%s< (offset now %d)\n", STR2CSTR(word), STR2CSTR(rword), offset); } //push the substituted line to result rb_ary_push(result, sline); c++; } //free checker delete_aspell_document_checker(checker); } else { rb_raise(cAspellError, "%s", "No block given. How to correct?"); } return result; }
/* Remeber to free returned string */ char * spelling_document_line(struct spelling_document *sd, char *in_line) { char *newline; int diff, line_len; size_t line_size, conv_line; struct AspellToken token; char *line; size_t conv_in; line = spelling_conv(sd->spelling->conv, in_line); line_len = strlen(line); line_size = line_len + (line_len/10); if ((newline = malloc(line_size)) == NULL) return NULL; strcpy(newline, line); free(line); aspell_document_checker_process(sd->checker, newline, line_len); diff = 0; while (token = aspell_document_checker_next_misspelling(sd->checker), token.len != 0) { char *word_begin; const char *word; int word_len; const AspellWordList *wl; AspellStringEnumeration *els; word_begin = newline + token.offset + diff; wl = aspell_speller_suggest(sd->spelling->speller, word_begin, token.len); els = aspell_word_list_elements(wl); if ((word = aspell_string_enumeration_next(els)) == NULL) continue; word_len = strlen(word); diff += word_len - token.len; memmove(word_begin + word_len, word_begin + token.len, strlen(word_begin + token.len) + 1); memcpy(word_begin, word, word_len); line_len += diff; } line = spelling_conv(sd->spelling->conv_out, newline); free(newline); return line; }
void doSpellCheckDoc(GtkWidget* widget,gpointer data) { GtkTextIter start; GtkTextIter end; AspellCanHaveError* ret; AspellDocumentChecker* checker; AspellToken token; int diff; unsigned int goodwordlen; char* word_begin; char* badword; GtkTextIter startiter; GtkTextIter enditer; char* line; pageStruct* page=getPageStructPtr(-1); gtk_text_buffer_get_start_iter((GtkTextBuffer*)page->buffer,&startiter); gtk_text_buffer_get_end_iter((GtkTextBuffer*)page->buffer,&enditer); line=gtk_text_buffer_get_text((GtkTextBuffer*)page->buffer,&startiter,&enditer,false); /* Set up the document checker */ ret=new_aspell_document_checker(spellChecker); if (aspell_error(ret)!=0) { printf("Error: %s\n",aspell_error_message(ret)); return; } checker=to_aspell_document_checker(ret); /* First process the line */ aspell_document_checker_process(checker,line,-1); diff=0; /* Now find the misspellings in the line */ while(token=aspell_document_checker_next_misspelling(checker),token.len!=0) { /* Pay particular attention to how token.offset and diff is used */ asprintf(&badword,"%.*s",token.len,(char*)&line[token.offset+diff]); goodWord=NULL; checkTheWord(badword,1); if(cancelCheck==true) { delete_aspell_document_checker(checker); return; } word_begin=line+token.offset+diff; if(goodWord!=NULL) { goodwordlen=strlen(goodWord); /* Replace the misspelled word with the replacement */ diff+=goodwordlen-token.len; memmove(word_begin+goodwordlen,word_begin+token.len,strlen(word_begin+token.len)+1); memcpy(word_begin,goodWord,goodwordlen); } } delete_aspell_document_checker(checker); gtk_text_buffer_get_bounds((GtkTextBuffer*)page->buffer,&start,&end); gtk_text_buffer_select_range((GtkTextBuffer*)page->buffer,&start,&end); gtk_text_buffer_delete_selection((GtkTextBuffer*)page->buffer,true,true); gtk_text_buffer_get_start_iter((GtkTextBuffer*)page->buffer,&start); gtk_text_buffer_insert((GtkTextBuffer*)page->buffer,&start,line,-1); if(spellCheckWord!=NULL) { gtk_widget_destroy(spellCheckWord); spellCheckWord=NULL; } }
static void check_document(AspellSpeller * speller, const char * filename) { /* For readablity this function does not worry about buffer overrun. This is meant as an illustrative example only. Please do not attent to spell check your docuemnts with this function. */ AspellCanHaveError * ret; AspellDocumentChecker * checker; AspellToken token; FILE * doc, * out; char line[256], repl[256], checked_filename[256]; int diff; unsigned int repl_len; char * word_begin; /* Open the file */ doc = fopen(filename, "r"); if (doc == 0) { printf("Error: Unable to open the file \"%s\" for reading.", filename); return; } /* Open filename.checked for writing the results */ strcpy(checked_filename, filename); strcat(checked_filename, ".checked"); out = fopen(checked_filename, "w"); if (out == 0) { printf("Error: Unable to open the file \"%s\" for writing.", checked_filename); return; } /* Set up the document checker */ ret = new_aspell_document_checker(speller); if (aspell_error(ret) != 0) { printf("Error: %s\n",aspell_error_message(ret)); return; } checker = to_aspell_document_checker(ret); while (fgets(line, 256, doc)) { /* First process the line */ aspell_document_checker_process(checker, line, -1); diff = 0; /* Now find the misspellings in the line */ while (token = aspell_document_checker_next_misspelling(checker), token.len != 0) { /* Print out the misspelling and get a replasment from the user */ /* Pay particular attention to how token.offset and diff is used */ word_begin = line + token.offset + diff; printf("%.*s*%.*s*%s", (int)(token.offset + diff), line, (int)token.len, word_begin, word_begin + token.len); printf("Suggestions: "); print_word_list(speller, aspell_speller_suggest(speller, word_begin, token.len), ' '); printf("\n"); printf("Replacement? "); fgets(repl, 256, stdin); printf("\n"); if (repl[0] == '\n') continue; /* ignore the current misspelling */ repl_len = strlen(repl) - 1; repl[repl_len] = '\0'; /* Replace the misspelled word with the replacement */ diff += repl_len - token.len; memmove(word_begin + repl_len, word_begin + token.len, strlen(word_begin + token.len) + 1); memcpy(word_begin, repl, repl_len); } /* print the line to filename.checked */ fputs(line, out); } delete_aspell_document_checker(checker); printf("Done. Results saved to \"%s\".", checked_filename); }