[system] / trunk / pg / macros / dangerousMacros.pl Repository:
ViewVC logotype

Diff of /trunk/pg/macros/dangerousMacros.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1069 Revision 1080
1#!/usr/local/bin/webwork-perl 1
2 2
3 3
4#################################################################### 4####################################################################
5# Copyright @ 1995-1999 University of Rochester 5# Copyright @ 1995-1999 University of Rochester
6# All Rights Reserved 6# All Rights Reserved
7#################################################################### 7####################################################################
8 8
9#################################################################### 9####################################################################
10# 10#
11# dangerousMacros.pl contains macros with potentially dangerous commands 11# dangerousMacros.pl contains macros with potentially dangerous commands
12# such as require and eval. They can reference disk files for reading and 12# such as require and eval. They can reference disk files for reading and
13# writing and can create links. It may be necessary to modify certain addresses 13# writing and can create links. It may be necessary to modify certain addresses
14# in this file to make the scripts run in different environments. 14# in this file to make the scripts run in different environments.
15# 15#
16# 16#
17 17
20 dangerousMacros.pl --- located in the courseScripts directory 20 dangerousMacros.pl --- located in the courseScripts directory
21 21
22=head1 SYNPOSIS 22=head1 SYNPOSIS
23 23
24 loadMacros(macrofile1,macrofile2,...) 24 loadMacros(macrofile1,macrofile2,...)
25 25
26 insertGraph(graphObject); 26 insertGraph(graphObject);
27 returns a path to the file containing the graph image. 27 returns a path to the file containing the graph image.
28 28
29 tth(texString) 29 tth(texString)
30 returns an HTML version of the tex code passed to it. 30 returns an HTML version of the tex code passed to it.
31 31
32 alias(pathToFile); 32 alias(pathToFile);
33 returns URL which links to that file 33 returns URL which links to that file
34 34
35 35
36=head1 DESCRIPTION 36=head1 DESCRIPTION
37 37
38 38
39C<dangerousMacros.pl> contains macros with potentially dangerous commands 39C<dangerousMacros.pl> contains macros with potentially dangerous commands
40such as require and eval. They can reference disk files for reading and 40such as require and eval. They can reference disk files for reading and
41writing and can create links. It may be necessary to modify certain addresses 41writing and can create links. It may be necessary to modify certain addresses
42in this file to make the scripts run properly in different environments. 42in this file to make the scripts run properly in different environments.
43 43
44C<dangerousMacros.pl> is loaded and reinitialized 44C<dangerousMacros.pl> is loaded and reinitialized
45every time a new problem is rendered. 45every time a new problem is rendered.
62 62
63 63
64 The following considerations come into play. 64 The following considerations come into play.
65 65
66 * One needs to limit the access to modules for safety -- hence only 66 * One needs to limit the access to modules for safety -- hence only
67 modules in the F<courseScriptsDirectory> can be loaded. 67 modules in the F<courseScriptsDirectory> can be loaded.
68 68
69 * Loading them in dangerousMacros.pl is wasteful, since the modules 69 * Loading them in dangerousMacros.pl is wasteful, since the modules
70 would need to be reloaded everytime a new safe compartment is created. 70 would need to be reloaded everytime a new safe compartment is created.
71 (I believe that using require takes care of this.) 71 (I believe that using require takes care of this.)
72 72
73 * Loading GD within a safeCompartment creates infinite recurrsion in AUTOLOAD (probably a bug) 73 * Loading GD within a safeCompartment creates infinite recurrsion in AUTOLOAD (probably a bug)
74 hence this module is loaded by translate.pl and then shared with 74 hence this module is loaded by translate.pl and then shared with
75 the safe compartment. 75 the safe compartment.
76 76
77 * Other modules loaded by translate.pl are C<Exporter> and C<DynaLoader. 77 * Other modules loaded by translate.pl are C<Exporter> and C<DynaLoader.
78 78
79 * PGrandom is loaded by F<PG.pl> , since it is needed there. 79 * PGrandom is loaded by F<PG.pl> , since it is needed there.
80 80
81 81
82 82
83The module name spaces loaded in dangerousMacros are: 83The module name spaces loaded in dangerousMacros are:
84 84
85 PGrandom (if not previously loaded) 85 PGrandom (if not previously loaded)
86 WWPlot 86 WWPlot
87 Fun 87 Fun
88 Label 88 Label
89 Circle 89 Circle
90 90
91in addition the subroutine &evaluate_units is shared from the module Units. 91in addition the subroutine &evaluate_units is shared from the module Units.
92 92
93=cut 93=cut
94 94
95BEGIN { 95BEGIN {
96 be_strict(); # an alias for use strict. This means that all global variable must contain main:: as a prefix. 96 be_strict(); # an alias for use strict. This means that all global variable must contain main:: as a prefix.
97 97
98} 98}
99 99
100 100
101sub _dangerousMacros_init { 101sub _dangerousMacros_init {
102} 102}
125directory of the course C<($macroDirectory)> and then, if not found, in the WeBWorK courseScripts 125directory of the course C<($macroDirectory)> and then, if not found, in the WeBWorK courseScripts
126directory C<($courseScriptsDirectory)> where the default behavior of the PG language is defined. 126directory C<($courseScriptsDirectory)> where the default behavior of the PG language is defined.
127 127
128An individual course can modify the PG language, B<for that course only>, by 128An individual course can modify the PG language, B<for that course only>, by
129duplicating one of the macro files in the courseScripts directory and placing this 129duplicating one of the macro files in the courseScripts directory and placing this
130file in the macro directory for the course. The new file in the course 130file in the macro directory for the course. The new file in the course
131macro directory will now be used instead of the file in the courseScripts directory. 131macro directory will now be used instead of the file in the courseScripts directory.
132 132
133The new file in the course macro directory can by modified by adding macros or modifying existing macros. 133The new file in the course macro directory can by modified by adding macros or modifying existing macros.
134 134
135I< Modifying macros is for users with some experience.> 135I< Modifying macros is for users with some experience.>
136 136
137Modifying existing macros might break other standard macros or problems which depend on the 137Modifying existing macros might break other standard macros or problems which depend on the
138unmodified behavior of these macors so do this with great caution. 138unmodified behavior of these macors so do this with great caution.
139In addition problems which use new macros defined in these files or which depend on the 139In addition problems which use new macros defined in these files or which depend on the
140modified behavior of existing macros will not work in other courses unless the macros are also 140modified behavior of existing macros will not work in other courses unless the macros are also
141transferred to the new course. It helps to document the problems by indicating any special macros 141transferred to the new course. It helps to document the problems by indicating any special macros
142which the problems require. 142which the problems require.
143 143
144There is no facility for modifying or overloading a single macro. The entire file containing the macro 144There is no facility for modifying or overloading a single macro. The entire file containing the macro
155# ${main::macroDirectory} 155# ${main::macroDirectory}
156# ${main::courseScriptsDirectory} 156# ${main::courseScriptsDirectory}
157# Global macros used 157# Global macros used
158# None 158# None
159 159
160# Because of the need to use the directory variables it is tricky to define this 160# Because of the need to use the directory variables it is tricky to define this
161# in translate.pl since, as currently written, the directories are not available 161# in translate.pl since, as currently written, the directories are not available
162# at that time. Perhaps if I rewrite translate as an object that method will work. 162# at that time. Perhaps if I rewrite translate as an object that method will work.
163 163
164# The only difficulty with defining loadMacros inside the Safe compartment is that 164# The only difficulty with defining loadMacros inside the Safe compartment is that
165# the error reporting does not work with syntax errors. 165# the error reporting does not work with syntax errors.
166# A kludge using require works around this problem 166# A kludge using require works around this problem
169my ($macroDirectory, 169my ($macroDirectory,
170 $courseScriptsDirectory, 170 $courseScriptsDirectory,
171 $templateDirectory, 171 $templateDirectory,
172 $scriptDirectory, 172 $scriptDirectory,
173 ); 173 );
174 174
175sub loadMacros { 175sub loadMacros {
176 my @files = @_; 176 my @files = @_;
177 my $fileName; 177 my $fileName;
178 ############################################################################### 178 ###############################################################################
179 # At this point the directories have been defined from %envir and we can define 179 # At this point the directories have been defined from %envir and we can define
183 $macroDirectory = eval('$main::macroDirectory') unless defined($macroDirectory); 183 $macroDirectory = eval('$main::macroDirectory') unless defined($macroDirectory);
184 $courseScriptsDirectory = eval('$main::courseScriptsDirectory') unless defined($courseScriptsDirectory); 184 $courseScriptsDirectory = eval('$main::courseScriptsDirectory') unless defined($courseScriptsDirectory);
185 $templateDirectory = eval('$main::courseScriptsDirectory') unless defined($templateDirectory); 185 $templateDirectory = eval('$main::courseScriptsDirectory') unless defined($templateDirectory);
186 $scriptDirectory = eval('$main::scriptDirectory') unless defined($scriptDirectory); 186 $scriptDirectory = eval('$main::scriptDirectory') unless defined($scriptDirectory);
187 187
188 unless (defined( $main::externalTTHPath) and $main::externalTTHPath) { 188 unless (defined( $main::externalTTHPath) and $main::externalTTHPath) {
189 warn "WARNING::Please make sure that the DOCUMENT() statement comes before<BR>\n" . 189 warn "WARNING::Please make sure that the DOCUMENT() statement comes before<BR>\n" .
190 " the loadMacros() statement in the problem template.<p>" . 190 " the loadMacros() statement in the problem template.<p>" .
191 " The externalTTHPath variable |$main::externalTTHPath| was\n". 191 " The externalTTHPath variable |$main::externalTTHPath| was\n".
192 " not defined which usually indicates the problem above.<br>\n"; 192 " not defined which usually indicates the problem above.<br>\n";
193 193
194 } 194 }
195 #warn "running load macros"; 195 #warn "running load macros";
196 while (@files) { 196 while (@files) {
197 $fileName = shift @files; 197 $fileName = shift @files;
198 next if ($fileName =~ /^PG.pl$/) ; # the PG.pl macro package is already loaded. 198 next if ($fileName =~ /^PG.pl$/) ; # the PG.pl macro package is already loaded.
199 199
200 my $macro_file_name = $fileName; 200 my $macro_file_name = $fileName;
201 $macro_file_name =~s/\.pl//; # trim off the extension 201 $macro_file_name =~s/\.pl//; # trim off the extension
202 $macro_file_name =~s/\.pg//; # sometimes the extension is .pg (e.g. CAPA files) 202 $macro_file_name =~s/\.pg//; # sometimes the extension is .pg (e.g. CAPA files)
203 my $init_subroutine_name = "_${macro_file_name}_init"; 203 my $init_subroutine_name = "_${macro_file_name}_init";
204 my $macro_file_loaded; 204 my $macro_file_loaded;
215 ############################################################################### 215 ###############################################################################
216 216
217 local($temp::rf_init_subroutine); 217 local($temp::rf_init_subroutine);
218 eval qq{ \$temp::rf_init_subroutine = \\&main::$init_subroutine_name;}; 218 eval qq{ \$temp::rf_init_subroutine = \\&main::$init_subroutine_name;};
219 #warn "loadMacros: defining \$temp::rf_init_subroutine ",$temp::rf_init_subroutine; 219 #warn "loadMacros: defining \$temp::rf_init_subroutine ",$temp::rf_init_subroutine;
220 220
221 $macro_file_loaded = defined($temp::rf_init_subroutine) && defined( &{$temp::rf_init_subroutine} ); 221 $macro_file_loaded = defined($temp::rf_init_subroutine) && defined( &{$temp::rf_init_subroutine} );
222 222
223 # macros are searched for first in the $macroDirectory of the course 223 # macros are searched for first in the $macroDirectory of the course
224 # and then in the webwork $courseScripts directory. 224 # and then in the webwork $courseScripts directory.
225 unless ($macro_file_loaded) { 225 unless ($macro_file_loaded) {
226 #print STDERR "loadMacros: loading macro file $fileName\n"; 226 #print STDERR "loadMacros: loading macro file $fileName\n";
227 if (-r "${main::macroDirectory}$fileName") { 227 if (-r "${main::macroDirectory}$fileName") {
228 compile_file("${main::macroDirectory}$fileName"); 228 compile_file("${main::macroDirectory}$fileName");
229 229
230 } elsif (-r "${main::courseScriptsDirectory}$fileName" ) { 230 } elsif (-r "${main::courseScriptsDirectory}$fileName" ) {
231 compile_file("${main::courseScriptsDirectory}$fileName"); 231 compile_file("${main::courseScriptsDirectory}$fileName");
232 } else { 232 } else {
233 die "Can't locate macro file via path: |${main::macroDirectory}$fileName| or |${main::courseScriptsDirectory}$fileName|"; 233 die "Can't locate macro file via path: |${main::macroDirectory}$fileName| or |${main::courseScriptsDirectory}$fileName|";
234 } 234 }
235 } 235 }
236 # Try again to define the initialization subroutine. 236 # Try again to define the initialization subroutine.
240 if ( defined($temp::rf_init_subroutine) and defined( &{$temp::rf_init_subroutine} ) ) { 240 if ( defined($temp::rf_init_subroutine) and defined( &{$temp::rf_init_subroutine} ) ) {
241 #print " &$init_subroutine_name defined = ", $macro_file_loaded,"\n"; 241 #print " &$init_subroutine_name defined = ", $macro_file_loaded,"\n";
242 &{$temp::rf_init_subroutine}(); #initialize file 242 &{$temp::rf_init_subroutine}(); #initialize file
243 #print "initializing $init_subroutine_name\n"; 243 #print "initializing $init_subroutine_name\n";
244 } 244 }
245 245
246 } 246 }
247} 247}
248 248
249# errors in compiling macros is not always being reported. 249# errors in compiling macros is not always being reported.
250sub compile_file { 250sub compile_file {
256 my $string = <MACROFILE>; 256 my $string = <MACROFILE>;
257 my ($result,$error,$fullerror) = PG_restricted_eval($string); 257 my ($result,$error,$fullerror) = PG_restricted_eval($string);
258 if ($error) { # the $fullerror report has formatting and is never empty 258 if ($error) { # the $fullerror report has formatting and is never empty
259 $fullerror =~ s/\(eval \d+\)/ $filePath\n/; # attempt to insert file name instead of eval number 259 $fullerror =~ s/\(eval \d+\)/ $filePath\n/; # attempt to insert file name instead of eval number
260 die "Error detected while loading $filePath:\n$fullerror"; 260 die "Error detected while loading $filePath:\n$fullerror";
261 261
262 } 262 }
263 263
264 close(MACROFILE); 264 close(MACROFILE);
265 265
266} 266}
267 267
268# This creates on the fly graphs 268# This creates on the fly graphs
269 269
270=head2 insertGraph 270=head2 insertGraph
271 271
272 $filePath = insertGraph(graphObject); 272 $filePath = insertGraph(graphObject);
273 returns a path to the file containing the graph image. 273 returns a path to the file containing the graph image.
274 274
275insertGraph(graphObject) writes a gif file to the C<html/tmp/gif> directory of the current course. 275insertGraph(graphObject) writes a gif file to the C<html/tmp/gif> directory of the current course.
276The file name 276The file name
277is obtained from the graphObject. Warnings are issued if errors occur while writing to 277is obtained from the graphObject. Warnings are issued if errors occur while writing to
278the file. 278the file.
279 279
280The permissions and ownership of the file are controlled by C<$main::tmp_file_permission> 280The permissions and ownership of the file are controlled by C<$main::tmp_file_permission>
281and C<$main::numericalGroupID>. 281and C<$main::numericalGroupID>.
282 282
283B<Returns:> A string containing the full path to the temporary file containing the GIF image. 283B<Returns:> A string containing the full path to the temporary file containing the GIF image.
285 285
286 286
287InsertGraph draws the object $graph, stores it in "${tempDirectory}gif/$gifName.gif (or .png)" where 287InsertGraph draws the object $graph, stores it in "${tempDirectory}gif/$gifName.gif (or .png)" where
288the $imageName is obtained from the graph object. ConvertPath and surePathToTmpFile are used to insure 288the $imageName is obtained from the graph object. ConvertPath and surePathToTmpFile are used to insure
289that the correct directory separators are used for the platform and that the necessary directories 289that the correct directory separators are used for the platform and that the necessary directories
290are created if they are not already present. 290are created if they are not already present.
291 291
292The directory address to the file is the result. This is most often used in the construct 292The directory address to the file is the result. This is most often used in the construct
293 293
294 TEXT(alias(insertGraph($graph)) ); 294 TEXT(alias(insertGraph($graph)) );
295 295
296where alias converts the directory address to a URL when serving HTML pages and insures that 296where alias converts the directory address to a URL when serving HTML pages and insures that
297an eps file is generated when creating TeX code for downloading. 297an eps file is generated when creating TeX code for downloading.
298 298
299=cut 299=cut
300 300
301# Global variables used: 301# Global variables used:
302# $main::tmp_file_permission, 302# $main::tmp_file_permission,
303# $main::numericalGroupID 303# $main::numericalGroupID
304 304
305#Global macros used: 305#Global macros used:
306# &convertPath 306# &convertPath
307# &surePathToTmpFile 307# &surePathToTmpFile
308 308
309sub insertGraph { 309sub insertGraph {
310 # Convert the image to GIF and print it on standard output 310 # Convert the image to GIF and print it on standard output
311 my $graph = shift; 311 my $graph = shift;
312 my $extension = ($WWPlot::use_png) ? '.png' : '.gif'; 312 my $extension = ($WWPlot::use_png) ? '.png' : '.gif';
313 my $fileName = $graph->imageName . $extension; 313 my $fileName = $graph->imageName . $extension;
314 my $filePath = convertPath("gif/$fileName"); 314 my $filePath = convertPath("gif/$fileName");
315 $filePath = &surePathToTmpFile( $filePath ); 315 $filePath = &surePathToTmpFile( $filePath );
316 #createFile($filePath, $main::tmp_file_permission, $main::numericalGroupID); 316 #createFile($filePath, $main::tmp_file_permission, $main::numericalGroupID);
317 local(*OUTPUT); # create local file handle so it won't overwrite other open files. 317 local(*OUTPUT); # create local file handle so it won't overwrite other open files.
318 open(OUTPUT, ">$filePath")||warn ("$0","Can't open $filePath<BR>",""); 318 open(OUTPUT, ">$filePath")||warn ("$0","Can't open $filePath<BR>","");
327=head2 tth 327=head2 tth
328 328
329 tth(texString) 329 tth(texString)
330 returns an HTML version of the tex code passed to it. 330 returns an HTML version of the tex code passed to it.
331 331
332This macro sends the texString to the filter program C<tth> created by Ian Hutchinson. 332This macro sends the texString to the filter program C<tth> created by Ian Hutchinson.
333The tth program was created by Ian Hutchinson and is freely available 333The tth program was created by Ian Hutchinson and is freely available
334for B<non-commerical purposes> at the C<tth> main site: C<http://hutchinson.belmont.ma.us/tth/>. 334for B<non-commerical purposes> at the C<tth> main site: C<http://hutchinson.belmont.ma.us/tth/>.
335 335
336The purpose of C<tth> is to translate text in the TeX or Latex markup language into 336The purpose of C<tth> is to translate text in the TeX or Latex markup language into
337HTML markup as best as possible. Some symbols, such as square root symbols are not 337HTML markup as best as possible. Some symbols, such as square root symbols are not
338translated completely. Macintosh users must use the "MacRoman" encoding (available in 4.0 and 338translated completely. Macintosh users must use the "MacRoman" encoding (available in 4.0 and
347on C<tth> is available at the C<tth> main site. 347on C<tth> is available at the C<tth> main site.
348 348
349This macro contains code which is system dependent and may need to be modified 349This macro contains code which is system dependent and may need to be modified
350to run on different systems. 350to run on different systems.
351 351
352=for html 352=for html
353The link to <CODE>tth</CODE> for <STRONG>non-commerical</STRONG> is 353The link to <CODE>tth</CODE> for <STRONG>non-commerical</STRONG> is
354<A HREF="http://hutchinson.belmont.ma.us/tth/">http://hutchinson.belmont.ma.us/tth/</A>. 354<A HREF="http://hutchinson.belmont.ma.us/tth/">http://hutchinson.belmont.ma.us/tth/</A>.
355Binaries for many operating systems are available as well as the source code. Links 355Binaries for many operating systems are available as well as the source code. Links
356describing how to obtain <CODE>tth</CODE> for commerical use are also available on this page. 356describing how to obtain <CODE>tth</CODE> for commerical use are also available on this page.
357 357
358=cut 358=cut
369 369
370my ($tthPreambleFile, $tthPreambleContents); # the contents of this file will not change during problem compilation 370my ($tthPreambleFile, $tthPreambleContents); # the contents of this file will not change during problem compilation
371 # it only needs to be read once 371 # it only needs to be read once
372sub tth { 372sub tth {
373 my $inputString = shift; 373 my $inputString = shift;
374 374
375 # read the contents of the tthPreamble.tex file, unless it has already been read 375 # read the contents of the tthPreamble.tex file, unless it has already been read
376 unless ( defined( $tthPreambleContents) ) { 376 unless ( defined( $tthPreambleContents) ) {
377 $tthPreambleFile = "${main::templateDirectory}tthPreamble.tex" if ( -r "${main::templateDirectory}tthPreamble.tex" ); 377 $tthPreambleFile = "${main::templateDirectory}tthPreamble.tex" if ( -r "${main::templateDirectory}tthPreamble.tex" );
378 if ( defined($tthPreambleFile) ) { 378 if ( defined($tthPreambleFile) ) {
379 local(*TTHIN); 379 local(*TTHIN);
380 open (TTHIN, "${main::templateDirectory}tthPreamble.tex") || die "Can't open file ${main::templateDirectory}tthPreamble.tex"; 380 open (TTHIN, "${main::templateDirectory}tthPreamble.tex") || die "Can't open file ${main::templateDirectory}tthPreamble.tex";
381 #my @tthPreambleArray = <TTHIN>; 381 #my @tthPreambleArray = <TTHIN>;
382 local($/); 382 local($/);
383 $/ = undef; 383 $/ = undef;
384 $tthPreambleContents = <TTHIN>;#join("",@tthPreambleArray); 384 $tthPreambleContents = <TTHIN>;#join("",@tthPreambleArray);
385 close(TTHIN); 385 close(TTHIN);
386 386
387 $tthPreambleContents =~ s/(.)\n/$1%\n/g; # thanks to Jim Martino 387 $tthPreambleContents =~ s/(.)\n/$1%\n/g; # thanks to Jim Martino
388 # each line in the definition file 388 # each line in the definition file
389 # should end with a % to prevent 389 # should end with a % to prevent
390 # adding supurious paragraphs to output. 390 # adding supurious paragraphs to output.
391 391
392 $tthPreambleContents .="%\n"; # solves the problem if the file doesn't end with a return. 392 $tthPreambleContents .="%\n"; # solves the problem if the file doesn't end with a return.
393 393
394 } else { 394 } else {
395 $tthPreambleContents = ""; 395 $tthPreambleContents = "";
396 } 396 }
397 } 397 }
398 398
399 $inputString = $tthPreambleContents . $inputString; 399 $inputString = $tthPreambleContents . $inputString;
400 $inputString = "<<END_OF_TTH_INPUT_STRING;\n\n\n" . $inputString . "\nEND_OF_TTH_INPUT_STRING\necho \"\" >/dev/null"; #it's not clear why another command is needed. 400 $inputString = "<<END_OF_TTH_INPUT_STRING;\n\n\n" . $inputString . "\nEND_OF_TTH_INPUT_STRING\necho \"\" >/dev/null"; #it's not clear why another command is needed.
401 401
402 # $tthpath is now taken from $Global::externalTTHPath via %envir. 402 # $tthpath is now taken from $Global::externalTTHPath via %envir.
403 my $tthpath = $envir{externalTTHPath}; 403 my $tthpath = $envir{externalTTHPath};
404 my $out; 404 my $out;
405 405
406 if (-x $tthpath ) { 406 if (-x $tthpath ) {
407 my $tthcmd = "$tthpath -L -f5 -u -r 2>/dev/null " . $inputString; 407 my $tthcmd = "$tthpath -L -f5 -u -r 2>/dev/null " . $inputString;
408 if (open(TTH, "$tthcmd |")) { 408 if (open(TTH, "$tthcmd |")) {
409 local($/); 409 local($/);
410 $/ = undef; 410 $/ = undef;
411 $out = <TTH>; 411 $out = <TTH>;
412 $/ = "\n"; 412 $/ = "\n";
413 close(TTH); 413 close(TTH);
417 } else { 417 } else {
418 $out = "<BR> Can't execute the program tth at |$tthpath|<BR>"; 418 $out = "<BR> Can't execute the program tth at |$tthpath|<BR>";
419 } 419 }
420 420
421 $out; 421 $out;
422} 422}
423 423
424# possible solution to the tth font problem? Works only for iCab. 424# possible solution to the tth font problem? Works only for iCab.
425sub symbolConvert { 425sub symbolConvert {
426 my $string = shift; 426 my $string = shift;
427 $string =~ s/\x5C/\&#092;/g; #\ 92 &#092; 427 $string =~ s/\x5C/\&#092;/g; #\ 92 &#092;
460my $math2imgCount = 0; 460my $math2imgCount = 0;
461 461
462sub math2img { 462sub math2img {
463 my $tex = shift; 463 my $tex = shift;
464 my $mode = shift; 464 my $mode = shift;
465 465
466 my $sourcePath = $envir{templateDirectory} . "/" . $envir{fileName}; 466 my $sourcePath = $envir{templateDirectory} . "/" . $envir{fileName};
467 my $tempFile = "m2i/$envir{studentLogin}.$envir{setNumber}.$envir{probNum}." 467 my $tempFile = "m2i/$envir{studentLogin}.$envir{setNumber}.$envir{probNum}."
468 . $math2imgCount++ . ".png"; 468 . $math2imgCount++ . ".png";
469 my $tempPath = surePathToTmpFile($tempFile); #my $tempPath = "$envir{tempDirectory}$tempFile"; 469 my $tempPath = surePathToTmpFile($tempFile); #my $tempPath = "$envir{tempDirectory}$tempFile";
470 my $tempURL = "$envir{tempURL}/$tempFile"; 470 my $tempURL = "$envir{tempURL}/$tempFile";
483 dvipng( 483 dvipng(
484 $envir{dvipngTempDir}, $envir{externalLaTeXPath}, 484 $envir{dvipngTempDir}, $envir{externalLaTeXPath},
485 $envir{externalDvipngPath}, $tex, $tempPath 485 $envir{externalDvipngPath}, $tex, $tempPath
486 ); 486 );
487 } 487 }
488 488
489 if (-e $tempPath) { 489 if (-e $tempPath) {
490 return "<img align=\"middle\" src=\"$tempURL\" alt=\"$tex\">" if $mode eq "inline"; 490 return "<img align=\"middle\" src=\"$tempURL\" alt=\"$tex\">" if $mode eq "inline";
491 return "<div align=\"center\"><img src=\"$tempURL\" alt=\"$tex\"></div>" if $mode eq "display"; 491 return "<div align=\"center\"><img src=\"$tempURL\" alt=\"$tex\"></div>" if $mode eq "display";
492 } else { 492 } else {
493 return "<b>[math2img failed]</b>"; 493 return "<b>[math2img failed]</b>";
505 $latex, # path to latex binary 505 $latex, # path to latex binary
506 $dvipng, # path to dvipng binary 506 $dvipng, # path to dvipng binary
507 $tex, # tex string representing equation 507 $tex, # tex string representing equation
508 $targetPath # location of resulting image file 508 $targetPath # location of resulting image file
509 ) = @_; 509 ) = @_;
510 510
511 my $dvipngBroken = 0; 511 my $dvipngBroken = 0;
512 512
513 my $texFile = "$wd/equation.tex"; 513 my $texFile = "$wd/equation.tex";
514 my $dviFile = "$wd/equation.dvi"; 514 my $dviFile = "$wd/equation.dvi";
515 my $dviFile2 = "$wd/equationequation.dvi"; 515 my $dviFile2 = "$wd/equationequation.dvi";
516 my $dviCall = "equation"; 516 my $dviCall = "equation";
517 my $pngFile = "$wd/equation1.png"; 517 my $pngFile = "$wd/equation1.png";
518 518
519 unless (-e $wd) { 519 unless (-e $wd) {
520 die "dvipng working directory $wd doesn't exist -- caller should have created it for us!\n"; 520 die "dvipng working directory $wd doesn't exist -- caller should have created it for us!\n";
521 return 0; 521 return 0;
522 } 522 }
523 523
524 # write the tex file 524 # write the tex file
525 local *TEX; 525 local *TEX;
526 open TEX, ">", $texFile or warn "Failed to create $texFile: $!"; 526 open TEX, ">", $texFile or warn "Failed to create $texFile: $!";
527 print TEX <<'EOF'; 527 print TEX <<'EOF';
528% BEGIN HEADER 528% BEGIN HEADER
540% BEGIN FOOTER 540% BEGIN FOOTER
541\end{document} 541\end{document}
542% END FOOTER 542% END FOOTER
543EOF 543EOF
544 close TEX; 544 close TEX;
545 545
546 # call latex 546 # call latex
547 system "cd $wd && $latex $texFile" 547 system "cd $wd && $latex $texFile"
548 and warn "Failed to call $latex with $texFile: $!"; 548 and warn "Failed to call $latex with $texFile: $!";
549 549
550 unless (-e $dviFile) { 550 unless (-e $dviFile) {
551 warn "Failed to generate DVI file $dviFile"; 551 warn "Failed to generate DVI file $dviFile";
552 return 0; 552 return 0;
553 } 553 }
554 554
555 if ($dvipngBroken) { 555 if ($dvipngBroken) {
556 # change the name of the DVI file to get around dvipng's 556 # change the name of the DVI file to get around dvipng's
557 # crackheadedness. This is no longer needed with the newest 557 # crackheadedness. This is no longer needed with the newest
558 # version of dvipng (10 something) 558 # version of dvipng (10 something)
559 system "/bin/mv", $dviFile, $dviFile2; 559 system "/bin/mv", $dviFile, $dviFile2;
560 } 560 }
561 561
562 # call dvipng -- using warn instead of die passes some extra information 562 # call dvipng -- using warn instead of die passes some extra information
563 # back to the user the complete warning is still printed in the apache 563 # back to the user the complete warning is still printed in the apache
564 # error log and a simple message (math2img failed) is returned to the 564 # error log and a simple message (math2img failed) is returned to the
565 # webpage. 565 # webpage.
566 my $cmdout; 566 my $cmdout;
567 $cmdout = system "cd $wd && $dvipng $dviCall" 567 $cmdout = system "cd $wd && $dvipng $dviCall"
568 and warn "Failed to call$dvipng with $dviCall: $! with signal $cmdout"; 568 and warn "Failed to call$dvipng with $dviCall: $! with signal $cmdout";
569 569
570 unless (-e $pngFile) { 570 unless (-e $pngFile) {
571 warn "Failed to create PNG file $pngFile"; 571 warn "Failed to create PNG file $pngFile";
572 return 0; 572 return 0;
573 } 573 }
574 574
575 $cmdout = system "/bin/mv", $pngFile, $targetPath and warn "Failed to mv: /bin/mv $pngFile $targetPath $!. Call returned $cmdout. \n"; 575 $cmdout = system "/bin/mv", $pngFile, $targetPath and warn "Failed to mv: /bin/mv $pngFile $targetPath $!. Call returned $cmdout. \n";
576} 576}
577 577
578 578
579# ----- ----- ----- ----- 579# ----- ----- ----- -----
580 580
581=head2 alias 581=head2 alias
582 582
583 alias(pathToFile); 583 alias(pathToFile);
584 returns A string describing the URL which links to GIF or html file 584 returns A string describing the URL which links to GIF or html file
585 (in HTML and Latex2HTML modes). 585 (in HTML and Latex2HTML modes).
586 or a path to the appropriate eps version of a GIF file 586 or a path to the appropriate eps version of a GIF file
587 (TeX Mode) 587 (TeX Mode)
588 588
589 589
590 590
591C<alias> allows you to refer to auxiliary files which are in a directory along with 591C<alias> allows you to refer to auxiliary files which are in a directory along with
592the problem definition. In addition alias creates an eps copy of GIF files when 592the problem definition. In addition alias creates an eps copy of GIF files when
593downloading hard copy (TeX mode). 593downloading hard copy (TeX mode).
594 594
595As a rule auxiliary files that are used by 595As a rule auxiliary files that are used by
596a number of problems in a course should be placed in C<html/gif> or C<html> 596a number of problems in a course should be placed in C<html/gif> or C<html>
597or in a subdirectory of the C<html> directory, 597or in a subdirectory of the C<html> directory,
598while auxiliary files which are used in only one problem should be placed in 598while auxiliary files which are used in only one problem should be placed in
612start with the prefix defined in $Global:htmlDirectory. 612start with the prefix defined in $Global:htmlDirectory.
613 613
614B<When in TeX mode:> 614B<When in TeX mode:>
615 615
616 616
617GIF files will be translated into an eps file (using system dependent code) 617GIF files will be translated into an eps file (using system dependent code)
618and placed in the directory C<tmp/eps>. The full path to this file is returned 618and placed in the directory C<tmp/eps>. The full path to this file is returned
619for use by TeX in producing the hard copy. (This should work even in a chrooted 619for use by TeX in producing the hard copy. (This should work even in a chrooted
620environment.) in producing the hard copy. (This should work even in a chrooted 620environment.) in producing the hard copy. (This should work even in a chrooted
621environment.) 621environment.)
622 622
623The conversion is done by a system dependent script 623The conversion is done by a system dependent script
624called C<gif2eps> which should be in the scripts directory 624called C<gif2eps> which should be in the scripts directory
625 625
626The URL's for the other files are produced as in non-tex mode 626The URL's for the other files are produced as in non-tex mode
627but will of course not be active. 627but will of course not be active.
628 628
629=item Files in the tmp subdirectory 629=item Files in the tmp subdirectory
636start with the prefix defined in $Global:tempDirectory. 636start with the prefix defined in $Global:tempDirectory.
637 637
638B<When in TeX mode:> 638B<When in TeX mode:>
639 639
640 640
641GIF files will be translated into an eps file (using system dependent code) 641GIF files will be translated into an eps file (using system dependent code)
642and placed in the directory C<tmp/eps>. The full path to this file is returned 642and placed in the directory C<tmp/eps>. The full path to this file is returned
643for use by TeX in producing the hard copy. (This should work even in a chrooted 643for use by TeX in producing the hard copy. (This should work even in a chrooted
644environment.) 644environment.)
645 645
646The conversion is done by a system dependent script 646The conversion is done by a system dependent script
647called C<gif2eps> which should be in the scripts directory 647called C<gif2eps> which should be in the scripts directory
648 648
649The URL's for the other files are produced as in non-tex mode 649The URL's for the other files are produced as in non-tex mode
650but will of course not be active. 650but will of course not be active.
651 651
652=item Files in the course template subdirectory: 652=item Files in the course template subdirectory:
653 653
654B<When not in TeX mode:> 654B<When not in TeX mode:>
655 655
656If the file lies under the course templates subdirectory, 656If the file lies under the course templates subdirectory,
657it is assumed to lie in subdirectory rooted in the directory 657it is assumed to lie in subdirectory rooted in the directory
658containing the problem template file. 658containing the problem template file.
659An alias is created under the C<html/tmp/gif> or 659An alias is created under the C<html/tmp/gif> or
660C<html/tmp/html> directory and linked to the original file. 660C<html/tmp/html> directory and linked to the original file.
661The file path for this type of file is a relative 661The file path for this type of file is a relative
662path rooted at the directory containing the problem template file. 662path rooted at the directory containing the problem template file.
663 663
664B<When in TeX mode:> 664B<When in TeX mode:>
665 665
666GIF files will be translated into an eps file (using system dependent code) 666GIF files will be translated into an eps file (using system dependent code)
667and placed in the directory C<html/tmp/eps>. The full path to this file is returned 667and placed in the directory C<html/tmp/eps>. The full path to this file is returned
668for use by TeX in producing the hard copy. (This should work even in a chrooted 668for use by TeX in producing the hard copy. (This should work even in a chrooted
669environment.) 669environment.)
670 670
671The conversion is done by a system dependent script 671The conversion is done by a system dependent script
672called C<gif2eps> which should be in the scripts directory 672called C<gif2eps> which should be in the scripts directory
673 673
674The URL's for the other files are produced as in non-tex mode 674The URL's for the other files are produced as in non-tex mode
682 682
683# Currently gif, html and types are supported. 683# Currently gif, html and types are supported.
684# 684#
685# If the auxiliary file path has not extension then the extension .gif isassumed. 685# If the auxiliary file path has not extension then the extension .gif isassumed.
686# 686#
687# If the auxiliary file path leads to a file in the ${Global::htmlDirectory} 687# If the auxiliary file path leads to a file in the ${Global::htmlDirectory}
688# no changes are made to the file path. 688# no changes are made to the file path.
689# 689#
690# If the auxiliary file path is not complete, than it is assumed that it refers 690# If the auxiliary file path is not complete, than it is assumed that it refers
691# to a subdirectoy of the directory containing the problem.. 691# to a subdirectoy of the directory containing the problem..
692# 692#
693# The output is either the correct URL for the file 693# The output is either the correct URL for the file
694# or (in TeX mode) the complete path to the eps version of the file 694# or (in TeX mode) the complete path to the eps version of the file
695# and can be used as input into the image macro. 695# and can be used as input into the image macro.
696# 696#
697# surePathToTmpFile takes a path and outputs the complete path: 697# surePathToTmpFile takes a path and outputs the complete path:
698# ${main::htmlDirectory}/tmp/path 698# ${main::htmlDirectory}/tmp/path
699# It insures that all of the directories in the path have been created, 699# It insures that all of the directories in the path have been created,
700# but does not create the 700# but does not create the
701# final file. 701# final file.
702 702
703# For postscript printing, alias generates an eps version of the gif image and places 703# For postscript printing, alias generates an eps version of the gif image and places
704# it in the directory eps. This slows down downloading postscript versions somewhat, 704# it in the directory eps. This slows down downloading postscript versions somewhat,
705# but not excessivevly. 705# but not excessivevly.
706# Alias does not do any garbage collection, so files and alias may accumulate and 706# Alias does not do any garbage collection, so files and alias may accumulate and
707# need to be removed manually or by a reaper daemon. 707# need to be removed manually or by a reaper daemon.
708 708
709 709
710# Global variables used: 710# Global variables used:
711# $main::fileName # the full path to the current problem template file 711# $main::fileName # the full path to the current problem template file
726# directoryFromPath 726# directoryFromPath
727 727
728 728
729# This subroutine has commands which will not work on non-UNIX environments. 729# This subroutine has commands which will not work on non-UNIX environments.
730# system("cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output") && 730# system("cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output") &&
731 731
732 732
733# local constants $User, $psvn $setNumber $probNum $displayMode 733# local constants $User, $psvn $setNumber $probNum $displayMode
734 734
735sub sourceAlias { 735sub sourceAlias {
736 my $path_to_file = shift; 736 my $path_to_file = shift;
737 my $user = $main::inputs_ref->{user}; 737 my $user = $main::inputs_ref->{user};
738 $user = " " unless defined($user); 738 $user = " " unless defined($user);
739 my $out = "source.pl?probSetKey=$main::psvn". 739 my $out = "source.pl?probSetKey=$main::psvn".
740 "&amp;probNum=$main::probNum" . 740 "&amp;probNum=$main::probNum" .
741 "&amp;Mode=$main::displayMode" . 741 "&amp;Mode=$main::displayMode" .
742 "&amp;course=". $main::courseName . 742 "&amp;course=". $main::courseName .
743 "&amp;user=" . $user . 743 "&amp;user=" . $user .
744 "&amp;displayPath=$path_to_file" . 744 "&amp;displayPath=$path_to_file" .
745 "&amp;key=". $main::sessionKey; 745 "&amp;key=". $main::sessionKey;
746 746
747 $out; 747 $out;
748} 748}
749 749
750 750
751sub alias { 751sub alias {
758 #my $studentLogin = $main::studentLogin; 758 #my $studentLogin = $main::studentLogin;
759 #my $psvnNumber = $main::psvnNumber; 759 #my $psvnNumber = $main::psvnNumber;
760 #my $setNumber = $main::setNumber; 760 #my $setNumber = $main::setNumber;
761 #my $probNum = $main::probNum; 761 #my $probNum = $main::probNum;
762 #my $displayMode = $main::displayMode; 762 #my $displayMode = $main::displayMode;
763 763
764 764
765 my $aux_file_path = shift @_; 765 my $aux_file_path = shift @_;
766 warn "Empty string used as input into the function alias" unless $aux_file_path; 766 warn "Empty string used as input into the function alias" unless $aux_file_path;
767 767
768 # problem specific data 768 # problem specific data
769 warn "The path to the current problem file template is not defined." unless $main::fileName; 769 warn "The path to the current problem file template is not defined." unless $main::fileName;
770 warn "The current studentLogin is not defined " unless $main::studentLogin; 770 warn "The current studentLogin is not defined " unless $main::studentLogin;
771 warn "The current problem set number is not defined" if $main::setNumber eq ""; # allow for sets equal to 0 771 warn "The current problem set number is not defined" if $main::setNumber eq ""; # allow for sets equal to 0
772 warn "The current problem number is not defined" if $main::probNum eq ""; 772 warn "The current problem number is not defined" if $main::probNum eq "";
773 warn "The current problem set version number (psvn) is not defined" unless $main::psvnNumber; 773 warn "The current problem set version number (psvn) is not defined" unless $main::psvnNumber;
774 warn "The displayMode is not defined" unless $main::displayMode; 774 warn "The displayMode is not defined" unless $main::displayMode;
775 775
776 # required macros 776 # required macros
777 warn "The macro &surePathToTmpFile can't be found" unless defined(&surePathToTmpFile); 777 warn "The macro &surePathToTmpFile can't be found" unless defined(&surePathToTmpFile);
778 warn "The macro &convertPath can't be found" unless defined(&convertPath); 778 warn "The macro &convertPath can't be found" unless defined(&convertPath);
779 warn "The macro &directoryFromPath can't be found" unless defined(&directoryFromPath); 779 warn "The macro &directoryFromPath can't be found" unless defined(&directoryFromPath);
780 warn "Can't execute the gif2eps script at ${main::externalGif2EpsPath}" unless ( -x "${main::externalGif2EpsPath}" ); 780 warn "Can't execute the gif2eps script at ${main::externalGif2EpsPath}" unless ( -x "${main::externalGif2EpsPath}" );
781 warn "Can't execute the png2eps script at ${main::externalPng2EpsPath}" unless ( -x "${main::externalPng2EpsPath}" ); 781 warn "Can't execute the png2eps script at ${main::externalPng2EpsPath}" unless ( -x "${main::externalPng2EpsPath}" );
782 782
783 # required directory addresses (and URL address) 783 # required directory addresses (and URL address)
784 warn "htmlDirectory is not defined in $main::htmlDirectory" unless $main::htmlDirectory; 784 warn "htmlDirectory is not defined in $main::htmlDirectory" unless $main::htmlDirectory;
785 warn "htmlURL is not defined in \$main::htmlURL" unless $main::htmlURL; 785 warn "htmlURL is not defined in \$main::htmlURL" unless $main::htmlURL;
786 warn "tempURL is not defined in \$main::tempURL" unless $main::tempURL; 786 warn "tempURL is not defined in \$main::tempURL" unless $main::tempURL;
787 #warn "The scripts directory is not defined in \$main::scriptDirectory" unless $main::scriptDirectory; 787 #warn "The scripts directory is not defined in \$main::scriptDirectory" unless $main::scriptDirectory;
788 # with the creation of externalGif2EpsPath and externalPng2EpsPath, the scripts directory is no longer used 788 # with the creation of externalGif2EpsPath and externalPng2EpsPath, the scripts directory is no longer used
789 789
790 # determine extension, if there is one 790 # determine extension, if there is one
791 # if extension exists, strip and use the value for $ext 791 # if extension exists, strip and use the value for $ext
792 # files without extensions are considered to be picture files: 792 # files without extensions are considered to be picture files:
793 793
794 my $ext; 794 my $ext;
795 if ($aux_file_path =~ s/\.([^\.]*)$// ) { 795 if ($aux_file_path =~ s/\.([^\.]*)$// ) {
796 $ext = $1; 796 $ext = $1;
797 } else { 797 } else {
798 warn "This file name $aux_file_path did not have an extension.<BR> " . 798 warn "This file name $aux_file_path did not have an extension.<BR> " .
799 "Every file name used as an argument to alias must have an extension.<BR> " . 799 "Every file name used as an argument to alias must have an extension.<BR> " .
800 "The permissable extensions are .gif, .png, and .html .<BR>"; 800 "The permissable extensions are .gif, .png, and .html .<BR>";
801 $ext = "gif"; 801 $ext = "gif";
802 } 802 }
803 803
804 # $adr_output is a url in HTML and Latex2HTML modes 804 # $adr_output is a url in HTML and Latex2HTML modes
805 # and a complete path in TEX mode. 805 # and a complete path in TEX mode.
806 my $adr_output; 806 my $adr_output;
807 807
808 # in order to facilitate maintenance of this macro the routines for handling 808 # in order to facilitate maintenance of this macro the routines for handling
809 # different file types are defined separately. This involves some redundancy 809 # different file types are defined separately. This involves some redundancy
810 # in the code but it makes it easier to define special handling for a new file 810 # in the code but it makes it easier to define special handling for a new file
811 # type, (but harder to change the behavior for all of the file types at once 811 # type, (but harder to change the behavior for all of the file types at once
812 # (sigh) ). 812 # (sigh) ).
813 813
814 814
815 if ($ext eq 'html') { 815 if ($ext eq 'html') {
816 ################################################################################ 816 ################################################################################
817 # .html FILES in HTML, HTML_tth, HTML_dpng, HTML_img and Latex2HTML mode 817 # .html FILES in HTML, HTML_tth, HTML_dpng, HTML_img and Latex2HTML mode
818 ################################################################################ 818 ################################################################################
819 819
820 # No changes are made for auxiliary files in the 820 # No changes are made for auxiliary files in the
821 # ${Global::htmlDirectory} subtree. 821 # ${Global::htmlDirectory} subtree.
822 if ( $aux_file_path =~ m|^$main::tempDirectory| ) { 822 if ( $aux_file_path =~ m|^$main::tempDirectory| ) {
823 $adr_output = $aux_file_path; 823 $adr_output = $aux_file_path;
824 $adr_output =~ s|$main::tempDirectory|$main::tempURL/|; 824 $adr_output =~ s|$main::tempDirectory|$main::tempURL/|;
825 $adr_output .= ".$ext"; 825 $adr_output .= ".$ext";
826 } elsif ($aux_file_path =~ m|^$main::htmlDirectory| ) { 826 } elsif ($aux_file_path =~ m|^$main::htmlDirectory| ) {
827 $adr_output = $aux_file_path; 827 $adr_output = $aux_file_path;
828 $adr_output =~ s|$main::htmlDirectory|$main::htmlURL|; 828 $adr_output =~ s|$main::htmlDirectory|$main::htmlURL|;
829 $adr_output .= ".$ext"; 829 $adr_output .= ".$ext";
830 } else { 830 } else {
831 # HTML files not in the htmlDirectory are assumed under live under the 831 # HTML files not in the htmlDirectory are assumed under live under the
832 # templateDirectory in the same directory as the problem. 832 # templateDirectory in the same directory as the problem.
833 # Create an alias file (link) in the directory html/tmp/html which 833 # Create an alias file (link) in the directory html/tmp/html which
834 # points to the original file and return the URL of this alias. 834 # points to the original file and return the URL of this alias.
835 # Create all of the subdirectories of html/tmp/html which are needed 835 # Create all of the subdirectories of html/tmp/html which are needed
836 # using sure file to path. 836 # using sure file to path.
837 837
838 # $fileName is obtained from environment for PGeval 838 # $fileName is obtained from environment for PGeval
839 # it gives the full path to the current problem 839 # it gives the full path to the current problem
840 my $filePath = directoryFromPath($main::fileName); 840 my $filePath = directoryFromPath($main::fileName);
841 my $htmlFileSource = convertPath("$main::templateDirectory${filePath}$aux_file_path.html"); 841 my $htmlFileSource = convertPath("$main::templateDirectory${filePath}$aux_file_path.html");
842 my $link = "html/$main::studentLogin-$main::psvnNumber-set$main::setNumber-prob$main::probNum-$aux_file_path.$ext"; 842 my $link = "html/$main::studentLogin-$main::psvnNumber-set$main::setNumber-prob$main::probNum-$aux_file_path.$ext";
843 my $linkPath = surePathToTmpFile($link); 843 my $linkPath = surePathToTmpFile($link);
844 $adr_output = "${main::tempURL}$link"; 844 $adr_output = "${main::tempURL}$link";
845 if (-e $htmlFileSource) { 845 if (-e $htmlFileSource) {
846 if (-e $linkPath) { 846 if (-e $linkPath) {
847 unlink($linkPath) || warn "Unable to unlink alias file at |$linkPath|"; 847 unlink($linkPath) || warn "Unable to unlink alias file at |$linkPath|";
848 # destroy the old link. 848 # destroy the old link.
849 } 849 }
850 symlink( $htmlFileSource, $linkPath) 850 symlink( $htmlFileSource, $linkPath)
851 || warn "The macro alias cannot create a link from |$linkPath| to |$htmlFileSource| <BR>" ; 851 || warn "The macro alias cannot create a link from |$linkPath| to |$htmlFileSource| <BR>" ;
852 } else { 852 } else {
853 warn("The macro alias cannot find an HTML file at: |$htmlFileSource|"); 853 warn("The macro alias cannot find an HTML file at: |$htmlFileSource|");
854 } 854 }
855 } 855 }
856 } elsif ($ext eq 'gif') { 856 } elsif ($ext eq 'gif') {
857 if ( $main::displayMode eq 'HTML' || 857 if ( $main::displayMode eq 'HTML' ||
858 $main::displayMode eq 'HTML_tth'|| 858 $main::displayMode eq 'HTML_tth'||
859 $main::displayMode eq 'HTML_dpng'|| 859 $main::displayMode eq 'HTML_dpng'||
860 $main::displayMode eq 'HTML_img'|| 860 $main::displayMode eq 'HTML_img'||
861 $main::displayMode eq 'Latex2HTML') { 861 $main::displayMode eq 'Latex2HTML') {
862 ################################################################################ 862 ################################################################################
863 # .gif FILES in HTML, HTML_tth, HTML_dpng, HTML_img, and Latex2HTML modes 863 # .gif FILES in HTML, HTML_tth, HTML_dpng, HTML_img, and Latex2HTML modes
864 ################################################################################ 864 ################################################################################
865 865
866 #warn "tempDirectory is $main::tempDirectory"; 866 #warn "tempDirectory is $main::tempDirectory";
867 #warn "file Path for auxiliary file is $aux_file_path"; 867 #warn "file Path for auxiliary file is $aux_file_path";
868 868
869 # No changes are made for auxiliary files in the htmlDirectory or in the tempDirectory subtree. 869 # No changes are made for auxiliary files in the htmlDirectory or in the tempDirectory subtree.
870 if ( $aux_file_path =~ m|^$main::tempDirectory| ) { 870 if ( $aux_file_path =~ m|^$main::tempDirectory| ) {
871 $adr_output = $aux_file_path; 871 $adr_output = $aux_file_path;
872 $adr_output =~ s|$main::tempDirectory|$main::tempURL|; 872 $adr_output =~ s|$main::tempDirectory|$main::tempURL|;
873 $adr_output .= ".$ext"; 873 $adr_output .= ".$ext";
874 #warn "adress out is $adr_output"; 874 #warn "adress out is $adr_output";
875 } elsif ($aux_file_path =~ m|^$main::htmlDirectory| ) { 875 } elsif ($aux_file_path =~ m|^$main::htmlDirectory| ) {
876 $adr_output = $aux_file_path; 876 $adr_output = $aux_file_path;
877 $adr_output =~ s|$main::htmlDirectory|$main::htmlURL|; 877 $adr_output =~ s|$main::htmlDirectory|$main::htmlURL|;
878 $adr_output .= ".$ext"; 878 $adr_output .= ".$ext";
879 } else { 879 } else {
880 # files not in the htmlDirectory sub tree are assumed to live under the templateDirectory 880 # files not in the htmlDirectory sub tree are assumed to live under the templateDirectory
881 # subtree in the same directory as the problem. 881 # subtree in the same directory as the problem.
882 882
883 # For a gif file the alias macro creates an alias under the html/images directory 883 # For a gif file the alias macro creates an alias under the html/images directory
884 # which points to the gif file in the problem directory. 884 # which points to the gif file in the problem directory.
885 # All of the subdirectories of html/tmp/gif which are needed are also created. 885 # All of the subdirectories of html/tmp/gif which are needed are also created.
886 my $filePath = directoryFromPath($main::fileName); 886 my $filePath = directoryFromPath($main::fileName);
887 887
888 # $fileName is obtained from environment for PGeval 888 # $fileName is obtained from environment for PGeval
889 # it gives the full path to the current problem 889 # it gives the full path to the current problem
890 my $gifSourceFile = convertPath("$main::templateDirectory${filePath}$aux_file_path.gif"); 890 my $gifSourceFile = convertPath("$main::templateDirectory${filePath}$aux_file_path.gif");
891 #my $link = "gif/$main::studentLogin-$main::psvnNumber-set$main::setNumber-prob$main::probNum-$aux_file_path.$ext"; 891 #my $link = "gif/$main::studentLogin-$main::psvnNumber-set$main::setNumber-prob$main::probNum-$aux_file_path.$ext";
892 my $link = "gif/$main::setNumber-prob$main::probNum-$aux_file_path.$ext"; 892 my $link = "gif/$main::setNumber-prob$main::probNum-$aux_file_path.$ext";
893 893
894 my $linkPath = surePathToTmpFile($link); 894 my $linkPath = surePathToTmpFile($link);
895 $adr_output = "${main::tempURL}$link"; 895 $adr_output = "${main::tempURL}$link";
896 #warn "linkPath is $linkPath"; 896 #warn "linkPath is $linkPath";
897 #warn "adr_output is $adr_output"; 897 #warn "adr_output is $adr_output";
898 if (-e $gifSourceFile) { 898 if (-e $gifSourceFile) {
907 } 907 }
908 } elsif ($main::displayMode eq 'TeX') { 908 } elsif ($main::displayMode eq 'TeX') {
909 ################################################################################ 909 ################################################################################
910 # .gif FILES in TeX mode 910 # .gif FILES in TeX mode
911 ################################################################################ 911 ################################################################################
912 912
913 if ($envir{texDisposition} eq "pdf") { 913 if ($envir{texDisposition} eq "pdf") {
914 # We're going to create PDF files with our TeX (using pdflatex), so we 914 # We're going to create PDF files with our TeX (using pdflatex), so we
915 # need images in PNG format. 915 # need images in PNG format.
916 916
917 my $gifFilePath; 917 my $gifFilePath;
918 918
919 if ($aux_file_path =~ m/^$main::htmlDirectory/ or $aux_file_path =~ m/^$main::tempDirectory/) { 919 if ($aux_file_path =~ m/^$main::htmlDirectory/ or $aux_file_path =~ m/^$main::tempDirectory/) {
920 # we've got a full pathname to a file 920 # we've got a full pathname to a file
921 $gifFilePath = "$aux_file_path.gif"; 921 $gifFilePath = "$aux_file_path.gif";
922 } else { 922 } else {
923 # we assume the file is in the same directory as the problem source file 923 # we assume the file is in the same directory as the problem source file
924 $gifFilePath = $main::templateDirectory . directoryFromPath($main::fileName) . "$aux_file_path.gif"; 924 $gifFilePath = $main::templateDirectory . directoryFromPath($main::fileName) . "$aux_file_path.gif";
925 } 925 }
926 926
927 my $gifFileName = fileFromPath($gifFilePath); 927 my $gifFileName = fileFromPath($gifFilePath);
928 928
929 $gifFileName =~ /^(.*)\.gif$/; 929 $gifFileName =~ /^(.*)\.gif$/;
930 my $pngFilePath = surePathToTmpFile("$main::tempDirectory/png/$1.png"); 930 my $pngFilePath = surePathToTmpFile("$main::tempDirectory/png/$1.png");
931 my $returnCode = system "$envir{externalGif2PngPath} $gifFilePath $pngFilePath"; 931 my $returnCode = system "$envir{externalGif2PngPath} $gifFilePath $pngFilePath";
932 932
933 if ($returnCode or not -e $pngFilePath) { 933 if ($returnCode or not -e $pngFilePath) {
934 die "failed to convert gif->png with $envir{externalGif2PngPath}: $!\n"; 934 die "failed to convert gif->png with $envir{externalGif2PngPath}: $!\n";
935 } 935 }
936 936
937 $adr_output = $pngFilePath; 937 $adr_output = $pngFilePath;
938 } else { 938 } else {
939 # Since we're not creating PDF files, we're probably just using a plain 939 # Since we're not creating PDF files, we're probably just using a plain
940 # vanilla latex. Hence, we need EPS images. 940 # vanilla latex. Hence, we need EPS images.
941 941
942 ################################################################################ 942 ################################################################################
943 # This is statement used below is system dependent. 943 # This is statement used below is system dependent.
944 # Notice that the range of colors is restricted when converting to postscript to keep the files small 944 # Notice that the range of colors is restricted when converting to postscript to keep the files small
945 # "cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmtops -noturn > $adr_output" 945 # "cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmtops -noturn > $adr_output"
946 # "cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn > $adr_output" 946 # "cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn > $adr_output"
947 ################################################################################ 947 ################################################################################
948 if ($aux_file_path =~ m|^$main::htmlDirectory| or $aux_file_path =~ m|^$main::tempDirectory|) { 948 if ($aux_file_path =~ m|^$main::htmlDirectory| or $aux_file_path =~ m|^$main::tempDirectory|) {
949 # To serve an eps file copy an eps version of the gif file to the subdirectory of eps/ 949 # To serve an eps file copy an eps version of the gif file to the subdirectory of eps/
950 my $linkPath = directoryFromPath($main::fileName); 950 my $linkPath = directoryFromPath($main::fileName);
951 951
952 my $gifSourceFile = "$aux_file_path.gif"; 952 my $gifSourceFile = "$aux_file_path.gif";
982 } 982 }
983 } else { 983 } else {
984 wwerror("Error in alias: dangerousMacros.pl","unrecognizable displayMode = $main::displayMode",""); 984 wwerror("Error in alias: dangerousMacros.pl","unrecognizable displayMode = $main::displayMode","");
985 } 985 }
986 } elsif ($ext eq 'png') { 986 } elsif ($ext eq 'png') {
987 if ( $main::displayMode eq 'HTML' || 987 if ( $main::displayMode eq 'HTML' ||
988 $main::displayMode eq 'HTML_tth'|| 988 $main::displayMode eq 'HTML_tth'||
989 $main::displayMode eq 'HTML_dpng'|| 989 $main::displayMode eq 'HTML_dpng'||
990 $main::displayMode eq 'HTML_img'|| 990 $main::displayMode eq 'HTML_img'||
991 $main::displayMode eq 'Latex2HTML') { 991 $main::displayMode eq 'Latex2HTML') {
992 ################################################################################ 992 ################################################################################
993 # .png FILES in HTML, HTML_tth, HTML_dpng, HTML_img, and Latex2HTML modes 993 # .png FILES in HTML, HTML_tth, HTML_dpng, HTML_img, and Latex2HTML modes
994 ################################################################################ 994 ################################################################################
995 995
996 #warn "tempDirectory is $main::tempDirectory"; 996 #warn "tempDirectory is $main::tempDirectory";
997 #warn "file Path for auxiliary file is $aux_file_path"; 997 #warn "file Path for auxiliary file is $aux_file_path";
998 998
999 # No changes are made for auxiliary files in the htmlDirectory or in the tempDirectory subtree. 999 # No changes are made for auxiliary files in the htmlDirectory or in the tempDirectory subtree.
1000 if ( $aux_file_path =~ m|^$main::tempDirectory| ) { 1000 if ( $aux_file_path =~ m|^$main::tempDirectory| ) {
1001 $adr_output = $aux_file_path; 1001 $adr_output = $aux_file_path;
1002 $adr_output =~ s|$main::tempDirectory|$main::tempURL|; 1002 $adr_output =~ s|$main::tempDirectory|$main::tempURL|;
1003 $adr_output .= ".$ext"; 1003 $adr_output .= ".$ext";
1004 #warn "adress out is $adr_output"; 1004 #warn "adress out is $adr_output";
1005 } elsif ($aux_file_path =~ m|^$main::htmlDirectory| ) { 1005 } elsif ($aux_file_path =~ m|^$main::htmlDirectory| ) {
1006 $adr_output = $aux_file_path; 1006 $adr_output = $aux_file_path;
1007 $adr_output =~ s|$main::htmlDirectory|$main::htmlURL|; 1007 $adr_output =~ s|$main::htmlDirectory|$main::htmlURL|;
1008 $adr_output .= ".$ext"; 1008 $adr_output .= ".$ext";
1009 } else { 1009 } else {
1010 # files not in the htmlDirectory sub tree are assumed to live under the templateDirectory 1010 # files not in the htmlDirectory sub tree are assumed to live under the templateDirectory
1011 # subtree in the same directory as the problem. 1011 # subtree in the same directory as the problem.
1012 1012
1013 # For a png file the alias macro creates an alias under the html/images directory 1013 # For a png file the alias macro creates an alias under the html/images directory
1014 # which points to the png file in the problem directory. 1014 # which points to the png file in the problem directory.
1015 # All of the subdirectories of html/tmp/gif which are needed are also created. 1015 # All of the subdirectories of html/tmp/gif which are needed are also created.
1016 my $filePath = directoryFromPath($main::fileName); 1016 my $filePath = directoryFromPath($main::fileName);
1017 1017
1018 # $fileName is obtained from environment for PGeval 1018 # $fileName is obtained from environment for PGeval
1019 # it gives the full path to the current problem 1019 # it gives the full path to the current problem
1020 my $pngSourceFile = convertPath("$main::templateDirectory${filePath}$aux_file_path.png"); 1020 my $pngSourceFile = convertPath("$main::templateDirectory${filePath}$aux_file_path.png");
1021 my $link = "gif/$main::studentLogin-$main::psvnNumber-set$main::setNumber-prob$main::probNum-$aux_file_path.$ext"; 1021 my $link = "gif/$main::studentLogin-$main::psvnNumber-set$main::setNumber-prob$main::probNum-$aux_file_path.$ext";
1022 my $linkPath = surePathToTmpFile($link); 1022 my $linkPath = surePathToTmpFile($link);
1039 ################################################################################ 1039 ################################################################################
1040 1040
1041 if ($envir{texDisposition} eq "pdf") { 1041 if ($envir{texDisposition} eq "pdf") {
1042 # We're going to create PDF files with our TeX (using pdflatex), so we 1042 # We're going to create PDF files with our TeX (using pdflatex), so we
1043 # need images in PNG format. what luck! they're already in PDF format! 1043 # need images in PNG format. what luck! they're already in PDF format!
1044 1044
1045 my $pngFilePath; 1045 my $pngFilePath;
1046 1046
1047 if ($aux_file_path =~ m/^$main::htmlDirectory/ or $aux_file_path =~ m/^$main::tempDirectory/) { 1047 if ($aux_file_path =~ m/^$main::htmlDirectory/ or $aux_file_path =~ m/^$main::tempDirectory/) {
1048 # we've got a full pathname to a file 1048 # we've got a full pathname to a file
1049 $pngFilePath = "$aux_file_path.png"; 1049 $pngFilePath = "$aux_file_path.png";
1050 } else { 1050 } else {
1051 # we assume the file is in the same directory as the problem source file 1051 # we assume the file is in the same directory as the problem source file
1052 $pngFilePath = $main::templateDirectory . directoryFromPath($main::fileName) . "$aux_file_path.png"; 1052 $pngFilePath = $main::templateDirectory . directoryFromPath($main::fileName) . "$aux_file_path.png";
1053 } 1053 }
1054 1054
1055 $adr_output = $pngFilePath; 1055 $adr_output = $pngFilePath;
1056 } else { 1056 } else {
1057 # Since we're not creating PDF files, we're probably just using a plain 1057 # Since we're not creating PDF files, we're probably just using a plain
1058 # vanilla latex. Hence, we need EPS images. 1058 # vanilla latex. Hence, we need EPS images.
1059 1059
1060 ################################################################################ 1060 ################################################################################
1061 # This is statement used below is system dependent. 1061 # This is statement used below is system dependent.
1062 # Notice that the range of colors is restricted when converting to postscript to keep the files small 1062 # Notice that the range of colors is restricted when converting to postscript to keep the files small
1063 # "cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmtops -noturn > $adr_output" 1063 # "cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmtops -noturn > $adr_output"
1064 # "cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn > $adr_output" 1064 # "cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn > $adr_output"
1065 ################################################################################ 1065 ################################################################################
1066 1066
1067 if ($aux_file_path =~ m|^$main::htmlDirectory| or $aux_file_path =~ m|^$main::tempDirectory|) { 1067 if ($aux_file_path =~ m|^$main::htmlDirectory| or $aux_file_path =~ m|^$main::tempDirectory|) {
1068 # To serve an eps file copy an eps version of the png file to the subdirectory of eps/ 1068 # To serve an eps file copy an eps version of the png file to the subdirectory of eps/
1069 my $linkPath = directoryFromPath($main::fileName); 1069 my $linkPath = directoryFromPath($main::fileName);
1103 } 1103 }
1104 } else { # $ext is not recognized 1104 } else { # $ext is not recognized
1105 ################################################################################ 1105 ################################################################################
1106 # FILES with unrecognized file extensions in any display modes 1106 # FILES with unrecognized file extensions in any display modes
1107 ################################################################################ 1107 ################################################################################
1108 1108
1109 warn "Error in the macro alias. Alias does not understand how to process files with extension $ext. (Path ot problem file is $main::fileName) "; 1109 warn "Error in the macro alias. Alias does not understand how to process files with extension $ext. (Path ot problem file is $main::fileName) ";
1110 } 1110 }
1111 1111
1112 warn "The macro alias was unable to form a URL for some auxiliary file used in this problem." unless $adr_output; 1112 warn "The macro alias was unable to form a URL for some auxiliary file used in this problem." unless $adr_output;
1113 return $adr_output; 1113 return $adr_output;
1114} 1114}
1115 1115
1116 1116
1117 1117
1118 1118
1119 1119
1120# Experiments 1120# Experiments
1121 1121
1122# It is important that these subroutines using sort are evaluated before 1122# It is important that these subroutines using sort are evaluated before
1123# the problem template is evaluated. 1123# the problem template is evaluated.
1124# Once the problem template has a "my $a;" susequent sort routines will not work. 1124# Once the problem template has a "my $a;" susequent sort routines will not work.
1125# 1125#
1126# PGsort can be used as a slightly slower but safer sort within problems. 1126# PGsort can be used as a slightly slower but safer sort within problems.
1127 1127
1133have special significance. 1133have special significance.
1134 1134
1135C<sort {$a<=>$b} @list> 1135C<sort {$a<=>$b} @list>
1136C<sort {$a cmp $b} @list> 1136C<sort {$a cmp $b} @list>
1137 1137
1138sorts the list numerically and lexically respectively. 1138sorts the list numerically and lexically respectively.
1139 1139
1140If C<my $a;> is used in a problem, before the sort routine is defined in a macro, then 1140If C<my $a;> is used in a problem, before the sort routine is defined in a macro, then
1141things get badly confused. To correct this, the following macros are defined in 1141things get badly confused. To correct this, the following macros are defined in
1142dangerougMacros.pl which is evaluated before the problem template is read. 1142dangerougMacros.pl which is evaluated before the problem template is read.
1143 1143
1161# trouble here when there was 1161# trouble here when there was
1162# more than one ans_eval in ANS() 1162# more than one ans_eval in ANS()
1163# No-one knows why? 1163# No-one knows why?
1164 1164
1165# This allows the use of i for imaginary numbers 1165# This allows the use of i for imaginary numbers
1166# one can write 3 +2i rather than 3+2i() 1166# one can write 3 +2i rather than 3+2i()
1167# 1167#
1168 1168
1169sub i; 1169sub i;
1170 1170
11711; # required to load properly 11711; # required to load properly

Legend:
Removed from v.1069  
changed lines
  Added in v.1080

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9