1#!/usr/bin/perl 2 3use CGI qw/ :standard /; 4use File::Temp qw/ tempfile tempdir /; 5 6# my $spellercss = '/speller/spellerStyle.css'; # by FredCK 7my $spellercss = '../spellerStyle.css'; # by FredCK 8# my $wordWindowSrc = '/speller/wordWindow.js'; # by FredCK 9my $wordWindowSrc = '../wordWindow.js'; # by FredCK 10my @textinputs = param( 'textinputs[]' ); # array 11# my $aspell_cmd = 'aspell'; # by FredCK (for Linux) 12my $aspell_cmd = '"C:\Program Files\Aspell\bin\aspell.exe"'; # by FredCK (for Windows) 13my $lang = 'en_US'; 14# my $aspell_opts = "-a --lang=$lang --encoding=utf-8"; # by FredCK 15my $aspell_opts = "-a --lang=$lang --encoding=utf-8 -H --rem-sgml-check=alt"; # by FredCK 16my $input_separator = "A"; 17 18# set the 'wordtext' JavaScript variable to the submitted text. 19sub printTextVar { 20 for( my $i = 0; $i <= $#textinputs; $i++ ) { 21 print "textinputs[$i] = decodeURIComponent('" . escapeQuote( $textinputs[$i] ) . "')\n"; 22 } 23} 24 25sub printTextIdxDecl { 26 my $idx = shift; 27 print "words[$idx] = [];\n"; 28 print "suggs[$idx] = [];\n"; 29} 30 31sub printWordsElem { 32 my( $textIdx, $wordIdx, $word ) = @_; 33 print "words[$textIdx][$wordIdx] = '" . escapeQuote( $word ) . "';\n"; 34} 35 36sub printSuggsElem { 37 my( $textIdx, $wordIdx, @suggs ) = @_; 38 print "suggs[$textIdx][$wordIdx] = ["; 39 for my $i ( 0..$#suggs ) { 40 print "'" . escapeQuote( $suggs[$i] ) . "'"; 41 if( $i < $#suggs ) { 42 print ", "; 43 } 44 } 45 print "];\n"; 46} 47 48sub printCheckerResults { 49 my $textInputIdx = -1; 50 my $wordIdx = 0; 51 my $unhandledText; 52 # create temp file 53 my $dir = tempdir( CLEANUP => 1 ); 54 my( $fh, $tmpfilename ) = tempfile( DIR => $dir ); 55 56 # temp file was created properly? 57 58 # open temp file, add the submitted text. 59 for( my $i = 0; $i <= $#textinputs; $i++ ) { 60 $text = url_decode( $textinputs[$i] ); 61 @lines = split( /\n/, $text ); 62 print $fh "\%\n"; # exit terse mode 63 print $fh "^$input_separator\n"; 64 print $fh "!\n"; # enter terse mode 65 for my $line ( @lines ) { 66 # use carat on each line to escape possible aspell commands 67 print $fh "^$line\n"; 68 } 69 70 } 71 # exec aspell command 72 my $cmd = "$aspell_cmd $aspell_opts < $tmpfilename 2>&1"; 73 open ASPELL, "$cmd |" or handleError( "Could not execute `$cmd`\\n$!" ) and return; 74 # parse each line of aspell return 75 for my $ret ( <ASPELL> ) { 76 chomp( $ret ); 77 # if '&', then not in dictionary but has suggestions 78 # if '#', then not in dictionary and no suggestions 79 # if '*', then it is a delimiter between text inputs 80 if( $ret =~ /^\*/ ) { 81 $textInputIdx++; 82 printTextIdxDecl( $textInputIdx ); 83 $wordIdx = 0; 84 85 } elsif( $ret =~ /^(&|#)/ ) { 86 my @tokens = split( " ", $ret, 5 ); 87 printWordsElem( $textInputIdx, $wordIdx, $tokens[1] ); 88 my @suggs = (); 89 if( $tokens[4] ) { 90 @suggs = split( ", ", $tokens[4] ); 91 } 92 printSuggsElem( $textInputIdx, $wordIdx, @suggs ); 93 $wordIdx++; 94 } else { 95 $unhandledText .= $ret; 96 } 97 } 98 close ASPELL or handleError( "Error executing `$cmd`\\n$unhandledText" ) and return; 99} 100 101sub escapeQuote { 102 my $str = shift; 103 $str =~ s/'/\\'/g; 104 return $str; 105} 106 107sub handleError { 108 my $err = shift; 109 print "error = '" . escapeQuote( $err ) . "';\n"; 110} 111 112sub url_decode { 113 local $_ = @_ ? shift : $_; 114 defined or return; 115 # change + signs to spaces 116 tr/+/ /; 117 # change hex escapes to the proper characters 118 s/%([a-fA-F0-9]{2})/pack "H2", $1/eg; 119 return $_; 120} 121 122# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 123# Display HTML 124# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 125 126print <<EOF; 127Content-type: text/html; charset=utf-8 128 129<html> 130<head> 131<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 132<link rel="stylesheet" type="text/css" href="$spellercss"/> 133<script src="$wordWindowSrc"></script> 134<script type="text/javascript"> 135var suggs = new Array(); 136var words = new Array(); 137var textinputs = new Array(); 138var error; 139EOF 140 141printTextVar(); 142 143printCheckerResults(); 144 145print <<EOF; 146var wordWindowObj = new wordWindow(); 147wordWindowObj.originalSpellings = words; 148wordWindowObj.suggestions = suggs; 149wordWindowObj.textInputs = textinputs; 150 151 152function init_spell() { 153 // check if any error occured during server-side processing 154 if( error ) { 155 alert( error ); 156 } else { 157 // call the init_spell() function in the parent frameset 158 if (parent.frames.length) { 159 parent.init_spell( wordWindowObj ); 160 } else { 161 error = "This page was loaded outside of a frameset. "; 162 error += "It might not display properly"; 163 alert( error ); 164 } 165 } 166} 167 168</script> 169 170</head> 171<body onLoad="init_spell();"> 172 173<script type="text/javascript"> 174wordWindowObj.writeBody(); 175</script> 176 177</body> 178</html> 179EOF 180 181