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