|
Spell checking in forms with Perl & JavaScript
|
Social links
Class::Prototype
WWW::Spyder Javascript tricks serial() join function Smart quotes Text to Excel Developing Featherweight Web Services with JavaScript
Miscellaneous
|
|
| Spell checking in forms... |
Update: There is a new bit of code I’ve put together to
abstract some of this stuff. I haven’t written it up yet and it’s
still just getting rounded out but it’s easy to use; check it
if you’re inclined: CGI::Form::Spell. Description I spell poorly. I have an English degree. The conclusion I want you to draw is not that English degrees make fine if uneconomical cage liners but that English is a difficult language to spell. I must note that being able to spell a word more than one way was once a sign of brightness. The Bard himself signed his name with different spellings. As we talked about already the power of Perl and JavaScript are a great match. In this CGI we use Perl’s interface to Aspell (Text::Aspell) to do spell checking of a textarea in a form and then use JavaScript to let the user voluntarily substitute out words which really aren’t correct with a simple click. You can use a few different spelling engines. The two that are common, well documented, and easily available with Perl are Ispell and Aspell. I have always used and enjoyed Ispell because it’s the default in Emacs. I recently discovered Aspell and I have to say it’s far superior at discerning what world you meant when you typed, for example, “diocsyribonewclayik.” Whether you guessed it or not, Aspell did, “deoxyribonucleic.” So, we’ll use Aspell for our example, though the functional interface of the main Perl module for Ispell makes it slightly more straightforward to implement in complex scripts. Code #!/usr/bin/perl use warnings; use strict; use Text::Aspell; use CGI qw(:standard); $CGI::POST_MAX = 2_000; # play nice now #===================================================================== print header, start_html(-title => 'Bad speling is bad'), script({-type => 'text/javascript',}, <<'SCRIPThere' function changeText(elmid, badword, goodword, optionid) { textBlock = document.getElementById(elmid); regex = new RegExp('\\b' + badword + '\\b', 'g'); textBlock.value = textBlock.value.replace(regex,goodword); option = document.getElementById(optionid); option.style.display = 'none'; } SCRIPThere ), start_form(), div({ -style => "position:absolute;top:25px;left:25px;"}, b("Enter text to spellcheck"), br, textarea( -class => 'textbox', -name => 'text1', -id => 'text1', -style => "width:250px;height:5em", -wrap => 'virtual', -rows => 9), ), div({-style => "position:absolute;top:55px;left:275px;"}, submit(-name => 'speling?', -style => 'z-index:99;'), ), div({-style => "position:absolute;top:25px;" . "left:360px;font-size:80%"}, do_spelling_feedback( 'text1', param('text1') ) ), end_form, end_html; exit 0; #===================================================================== # SUBROUTINES #===================================================================== sub do_spelling_feedback { my ( $field, $text ) = @_; warn "Field name missing in call to do_spelling_feedback()" unless $field; return '' unless $text; my $speller = get_speller(); my ( @badwords, %seen, $tail ); $tail = 'a'; while ( $text =~ /(['\w]+)/g ) { # add apos back my $word = $1; next if $seen{$word}++; unless ( $speller->check( $word ) ) { my @sug = $speller->suggest( $word ); # Five is plenty @sug = splice(@sug,0,6) if @sug > 6; my $rando_id = 'id_' . $tail++; my @link = map { a({-href=>'javascript:void()', -onclick => join('', "changeText('$field','", quotemeta($word), "','", quotemeta($_), "','$rando_id'", ")" ) }, $_ ) } @sug; push @badwords, div({-style=>"display:block", -id => $rando_id }, b({-style => 'background-color:#ff9;'. 'padding:0px 3px 0px 3px;'}, $word, ), div({-style => 'padding:0px 0px 4px 12px;'}, @link ? join(', ', @link) : "Sorry, no suggestion" ) ); } } return div( b("Click a word to make a correction",), br, join("\n", @badwords) ) if @badwords; return 'Everything looks okay. Try to misspell something.<br />' . a({-href=>'./spel.cgi?text1=Foor+ezampel,+yoo+culd+yuse+thise.'}, 'Foor ezampel, yoo culd yuse thise.'); } #===================================================================== sub get_speller { my $speller = Text::Aspell->new; die unless $speller; $speller->set_option('lang','en_US'); $speller->set_option('sug-mode','fast'); # the home-dir must exist & be read/write by the webserver user $speller->set_option('home-dir', '/www'); return $speller; } #===================================================================== sub add_to_dictionary { die "Not implemented -- " . "feel free to finish it out in your own app."; my $word = param('word'); print h2("Adding $word to dictionary"); my $speller = get_speller(); print $speller->add_to_personal($word) ? h3("success!") : h3("failed!"); $speller->save_all_word_lists; } #===================================================================== Discussion I’m sorry to report that Text::Aspell is not currently installed on this server and might never be and the Ispell implementation isn’t able to make proper suggestions. So you can’t demo this script here. If you have Aspell and Perl, you are more than welcome to copy the script and try it yourself. It is now here: Perl/JavaScript spelling checker. Please note, that server is not a dedicated box so it will not be up 100% of the time. If you try it and get nothing, try again a bit later. Here is the code without line numbers for easy copying. |
|
|
Perl Books ·
CPAN ·
mod_perl ·
Perl Monks ·
Perl Mongers ·
Perl Journal ·
Use Perl ·
Perl Jobs ·
ActiveState ·
perldoc.perl.org ·
O’Reilly Perl ·
W3Schools tutorials ·
Ovid's CGI Course ·
Catalyst ·
Perl at Wikipedia
Text, original code, fonts, and graphics ©1990-2008 Ashley Pond V. |
||