File: spel
#!/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;
}
#=====================================================================