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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1050 - (view) (download) (as text)

1 : sh002i 1050 #!/usr/local/bin/webwork-perl
2 :    
3 :    
4 :     ####################################################################
5 :     # Copyright @ 1995-1999 University of Rochester
6 :     # All Rights Reserved
7 :     ####################################################################
8 :    
9 :     ####################################################################
10 :     #
11 :     # dangerousMacros.pl contains macros with potentially dangerous commands
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
14 :     # in this file to make the scripts run in different environments.
15 :     #
16 :     #
17 :    
18 :     =head1 NAME
19 :    
20 :     dangerousMacros.pl --- located in the courseScripts directory
21 :    
22 :     =head1 SYNPOSIS
23 :    
24 :     loadMacros(macrofile1,macrofile2,...)
25 :    
26 :     insertGraph(graphObject);
27 :     returns a path to the file containing the graph image.
28 :    
29 :     tth(texString)
30 :     returns an HTML version of the tex code passed to it.
31 :    
32 :     alias(pathToFile);
33 :     returns URL which links to that file
34 :    
35 :    
36 :     =head1 DESCRIPTION
37 :    
38 :    
39 :     C<dangerousMacros.pl> contains macros with potentially dangerous commands
40 :     such as require and eval. They can reference disk files for reading and
41 :     writing and can create links. It may be necessary to modify certain addresses
42 :     in this file to make the scripts run properly in different environments.
43 :    
44 :     C<dangerousMacros.pl> is loaded and reinitialized
45 :     every time a new problem is rendered.
46 :    
47 :     =cut
48 :    
49 :    
50 :     ######## Dangerous macros#########
51 :     ## The macros in this file are defined while the safe compartment is wide open.
52 :     ## Be careful!
53 :     #########################################
54 :    
55 :    
56 :     =head2 Sharing modules:
57 :    
58 :     Most modules are loaded by dangerousMacros.pl
59 :    
60 :     The modules must be loaded using require (not use) since the courseScriptsDirectory is
61 :     defined at run time.
62 :    
63 :    
64 :     The following considerations come into play.
65 :    
66 :     * One needs to limit the access to modules for safety -- hence only
67 :     modules in the F<courseScriptsDirectory> can be loaded.
68 :    
69 :     * Loading them in dangerousMacros.pl is wasteful, since the modules
70 :     would need to be reloaded everytime a new safe compartment is created.
71 :     (I believe that using require takes care of this.)
72 :    
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
75 :     the safe compartment.
76 :    
77 :     * Other modules loaded by translate.pl are C<Exporter> and C<DynaLoader.
78 :    
79 :     * PGrandom is loaded by F<PG.pl> , since it is needed there.
80 :    
81 :    
82 :    
83 :     The module name spaces loaded in dangerousMacros are:
84 :    
85 :     PGrandom (if not previously loaded)
86 :     WWPlot
87 :     Fun
88 :     Label
89 :     Circle
90 :    
91 :     in addition the subroutine &evaluate_units is shared from the module Units.
92 :    
93 :     =cut
94 :    
95 :     BEGIN {
96 :     be_strict(); # an alias for use strict. This means that all global variable must contain main:: as a prefix.
97 :     }
98 :     sub _dangerousMacros_init {
99 :     }
100 :    
101 :     sub _dangerousMacros_export {
102 :     my @EXPORT= (
103 :     '&_dangerousMacros_init',
104 :     '&alias',
105 :     '&compile_file',
106 :     '&insertGraph',
107 :     '&loadMacros',
108 :     '&HEADER_TEXT',
109 :     '&sourceAlias',
110 :     '&tth',
111 :     );
112 :     @EXPORT;
113 :     }
114 :    
115 :    
116 :     =head2 loadMacros
117 :    
118 :     C<loadMacros(macrofile1,macrofile2,...)>
119 :    
120 :     loadMacros takes a list of file names and evaluates the contents of each file. This is used to load macros
121 :     which define and augment the PG language. The macro files are first searched for in the macro
122 :     directory of the course C<($macroDirectory)> and then, if not found, in the WeBWorK courseScripts
123 :     directory C<($courseScriptsDirectory)> where the default behavior of the PG language is defined.
124 :    
125 :     An individual course can modify the PG language, B<for that course only>, by
126 :     duplicating one of the macro files in the courseScripts directory and placing this
127 :     file in the macro directory for the course. The new file in the course
128 :     macro directory will now be used instead of the file in the courseScripts directory.
129 :    
130 :     The new file in the course macro directory can by modified by adding macros or modifying existing macros.
131 :    
132 :     I< Modifying macros is for users with some experience.>
133 :    
134 :     Modifying existing macros might break other standard macros or problems which depend on the
135 :     unmodified behavior of these macors so do this with great caution.
136 :     In addition problems which use new macros defined in these files or which depend on the
137 :     modified behavior of existing macros will not work in other courses unless the macros are also
138 :     transferred to the new course. It helps to document the problems by indicating any special macros
139 :     which the problems require.
140 :    
141 :     There is no facility for modifying or overloading a single macro. The entire file containing the macro
142 :     must be overloaded.
143 :    
144 :     Modifications to files in the course macros directory affect only that course,
145 :     they will not interfere with the normal behavior of B<WeBWorK> in other courses.
146 :    
147 :    
148 :    
149 :     =cut
150 :    
151 :     # Global variables used
152 :     # ${main::macroDirectory}
153 :     # ${main::courseScriptsDirectory}
154 :     # Global macros used
155 :     # None
156 :    
157 :     # Because of the need to use the directory variables it is tricky to define this
158 :     # in translate.pl since, as currently written, the directories are not available
159 :     # at that time. Perhaps if I rewrite translate as an object that method will work.
160 :    
161 :     # The only difficulty with defining loadMacros inside the Safe compartment is that
162 :     # the error reporting does not work with syntax errors.
163 :     # A kludge using require works around this problem
164 :    
165 :    
166 :     my ($macroDirectory,
167 :     $courseScriptsDirectory,
168 :     $templateDirectory,
169 :     $scriptDirectory,
170 :     );
171 :    
172 :     sub loadMacros {
173 :     my @files = @_;
174 :     my $fileName;
175 :     ###############################################################################
176 :     # At this point the directories have been defined from %envir and we can define
177 :     # the directories for this file
178 :     ###############################################################################
179 :    
180 :     $macroDirectory = eval('$main::macroDirectory') unless defined($macroDirectory);
181 :     $courseScriptsDirectory = eval('$main::courseScriptsDirectory') unless defined($courseScriptsDirectory);
182 :     $templateDirectory = eval('$main::courseScriptsDirectory') unless defined($templateDirectory);
183 :     $scriptDirectory = eval('$main::scriptDirectory') unless defined($scriptDirectory);
184 :    
185 :     # Hack to handle those problems where DOCUMENT() comes after loadMacros.
186 :     unless (defined( $main::externalTTHPath) and $main::externalTTHPath) {
187 :     warn "WARNING::Please make sure that the DOCUMENT() statement comes before<BR>\n" .
188 :     " the loadMacros() statement in the problem template.<p>" .
189 :     " The externalTTHPath variable |$main::externalTTHPath| was\n".
190 :     " not defined which usually indicates the problem above.<br>\n";
191 :    
192 :     }
193 :     #warn "running load macros";
194 :     while (@files) {
195 :     $fileName = shift @files;
196 :     next if ($fileName =~ /^PG.pl$/) ; # the PG.pl macro package is already loaded.
197 :    
198 :     my $macro_file_name = $fileName;
199 :     $macro_file_name =~s/\.pl//; # trim off the extension
200 :     $macro_file_name =~s/\.pg//; # sometimes the extension is .pg (e.g. CAPA files)
201 :     my $init_subroutine_name = "_${macro_file_name}_init";
202 :     my $macro_file_loaded;
203 :     #no strict;
204 :     ###############################################################################
205 :     # For some reason the "no stict" which works on webwork-db doesn't work on
206 :     # webwork. For this reason the constuction &{$init_subroutine_name}
207 :     # was abandoned and replaced by eval. This is considerably more dangerous
208 :     # since one could hide something nasty in a file name.
209 :     # Keep an eye on this ???
210 :     # webwork-db used perl 5.6.1 and webwork used perl 5.6.0 It seems
211 :     # unlikely that this was the problem. Otherwise all files seemed to
212 :     # be the same.
213 :     ###############################################################################
214 :    
215 :     local($temp::rf_init_subroutine);
216 :     eval qq{ \$temp::rf_init_subroutine = \\&main::$init_subroutine_name;};
217 :     #warn "loadMacros: defining \$temp::rf_init_subroutine ",$temp::rf_init_subroutine;
218 :    
219 :     $macro_file_loaded = defined($temp::rf_init_subroutine) && defined( &{$temp::rf_init_subroutine} );
220 :    
221 :     # macros are searched for first in the $macroDirectory of the course
222 :     # and then in the webwork $courseScripts directory.
223 :     unless ($macro_file_loaded) {
224 :     #print STDERR "loadMacros: loading macro file $fileName\n";
225 :     if (-r "${main::macroDirectory}$fileName") {
226 :     compile_file("${main::macroDirectory}$fileName");
227 :    
228 :     } elsif (-r "${main::courseScriptsDirectory}$fileName" ) {
229 :     compile_file("${main::courseScriptsDirectory}$fileName");
230 :     } else {
231 :     die "Can't locate macro file via path: |${main::macroDirectory}$fileName| or |${main::courseScriptsDirectory}$fileName|";
232 :     }
233 :     }
234 :     # Try again to define the initialization subroutine.
235 :     eval qq{ \$temp::rf_init_subroutine = \\&main::$init_subroutine_name;};
236 :     #warn "loadMacros: defining \$temp::rf_init_subroutine ",$temp::rf_init_subroutine;
237 :    
238 :     if ( defined($temp::rf_init_subroutine) and defined( &{$temp::rf_init_subroutine} ) ) {
239 :     #print " &$init_subroutine_name defined = ", $macro_file_loaded,"\n";
240 :     &{$temp::rf_init_subroutine}(); #initialize file
241 :     #print "initializing $init_subroutine_name\n";
242 :     }
243 :    
244 :     }
245 :     }
246 :    
247 :     # errors in compiling macros is not always being reported.
248 :     sub compile_file {
249 :     my $filePath = shift;
250 :     local(*MACROFILE);
251 :     local($/);
252 :     $/ = undef; # allows us to treat the file as a single line
253 :     open(MACROFILE, "<$filePath") || die "Cannot open file: $filePath";
254 :     my $string = <MACROFILE>;
255 :     my ($result,$error,$fullerror) = PG_restricted_eval($string);
256 :     if ($error) { # the $fullerror report has formatting and is never empty
257 :     $fullerror =~ s/\(eval \d+\)/ $filePath\n/; # attempt to insert file name instead of eval number
258 :     die "Error detected while loading $filePath:\n$fullerror";
259 :    
260 :     }
261 :    
262 :     close(MACROFILE);
263 :    
264 :     }
265 :    
266 :     # This creates on the fly graphs
267 :    
268 :     =head2 insertGraph
269 :    
270 :     $filePath = insertGraph(graphObject);
271 :     returns a path to the file containing the graph image.
272 :    
273 :     insertGraph(graphObject) writes a gif file to the C<html/tmp/gif> directory of the current course.
274 :     The file name
275 :     is obtained from the graphObject. Warnings are issued if errors occur while writing to
276 :     the file.
277 :    
278 :     The permissions and ownership of the file are controlled by C<$main::tmp_file_permission>
279 :     and C<$main::numericalGroupID>.
280 :    
281 :     B<Returns:> A string containing the full path to the temporary file containing the GIF image.
282 :    
283 :    
284 :    
285 :     InsertGraph draws the object $graph, stores it in "${tempDirectory}gif/$gifName.gif (or .png)" where
286 :     the $imageName is obtained from the graph object. ConvertPath and surePathToTmpFile are used to insure
287 :     that the correct directory separators are used for the platform and that the necessary directories
288 :     are created if they are not already present.
289 :    
290 :     The directory address to the file is the result. This is most often used in the construct
291 :    
292 :     TEXT(alias(insertGraph($graph)) );
293 :    
294 :     where alias converts the directory address to a URL when serving HTML pages and insures that
295 :     an eps file is generated when creating TeX code for downloading.
296 :    
297 :     =cut
298 :    
299 :     # Global variables used:
300 :     # $main::tmp_file_permission,
301 :     # $main::numericalGroupID
302 :    
303 :     #Global macros used:
304 :     # &convertPath
305 :     # &surePathToTmpFile
306 :    
307 :     sub insertGraph {
308 :     # Convert the image to GIF and print it on standard output
309 :     my $graph = shift;
310 :     my $extension = ($WWPlot::use_png) ? '.png' : '.gif';
311 :     my $fileName = $graph->imageName . $extension;
312 :     my $filePath = convertPath("gif/$fileName");
313 :     $filePath = &surePathToTmpFile( $filePath );
314 :     #createFile($filePath, $main::tmp_file_permission, $main::numericalGroupID);
315 :     local(*OUTPUT); # create local file handle so it won't overwrite other open files.
316 :     open(OUTPUT, ">$filePath")||warn ("$0","Can't open $filePath<BR>","");
317 :     chmod( 0777, $filePath);
318 :     print OUTPUT $graph->draw|| warn("$0","Can't print graph to $filePath<BR>","");
319 :     close(OUTPUT)||warn("$0","Can't close $filePath<BR>","");
320 :     $filePath;
321 :     }
322 :    
323 :    
324 :    
325 :     =head2 tth
326 :    
327 :     tth(texString)
328 :     returns an HTML version of the tex code passed to it.
329 :    
330 :     This macro sends the texString to the filter program C<tth> created by Ian Hutchinson.
331 :     The tth program was created by Ian Hutchinson and is freely available
332 :     for B<non-commerical purposes> at the C<tth> main site: C<http://hutchinson.belmont.ma.us/tth/>.
333 :    
334 :     The purpose of C<tth> is to translate text in the TeX or Latex markup language into
335 :     HTML markup as best as possible. Some symbols, such as square root symbols are not
336 :     translated completely. Macintosh users must use the "MacRoman" encoding (available in 4.0 and
337 :     higher browsers) in order to view the symbols correctly. WeBWorK attempts to force Macintosh
338 :     browsers to use this encoding when such a browser is detected.
339 :    
340 :     The contents of the file C<tthPreamble.tex> in the courses template directory are prepended
341 :     to each string. This allows one to define TeX macros which can be used in every problem.
342 :     Currently there is no default C<tthPreamble.tex> file, so if the file is not present in the
343 :     course template directory no TeX macro definitions are prepended. C<tth> already understands most
344 :     Latex commands, but will not, in general know I<AMS-Latex> commands. Additional information
345 :     on C<tth> is available at the C<tth> main site.
346 :    
347 :     This macro contains code which is system dependent and may need to be modified
348 :     to run on different systems.
349 :    
350 :     =for html
351 :     The link to <CODE>tth</CODE> for <STRONG>non-commerical</STRONG> is
352 :     <A HREF="http://hutchinson.belmont.ma.us/tth/">http://hutchinson.belmont.ma.us/tth/</A>.
353 :     Binaries for many operating systems are available as well as the source code. Links
354 :     describing how to obtain <CODE>tth</CODE> for commerical use are also available on this page.
355 :    
356 :     =cut
357 :    
358 :    
359 :    
360 :     # This file allows the tth display.
361 :     # Global variables:
362 :     # ${main::templateDirectory}tthPreamble.tex # location of any preamble TeX commands for tth
363 :     # ${main::templateDirectory}
364 :     # ${main::scriptDirectory}tth # path to tth application
365 :     # Global macros:
366 :     # None
367 :    
368 :     my ($tthPreambleFile, $tthPreambleContents); # the contents of this file will not change during problem compilation
369 :     # it only needs to be read once
370 :     sub tth {
371 :     my $inputString = shift;
372 :    
373 :     # read the contents of the tthPreamble.tex file, unless it has already been read
374 :     unless ( defined( $tthPreambleContents) ) {
375 :     $tthPreambleFile = "${main::templateDirectory}tthPreamble.tex" if ( -r "${main::templateDirectory}tthPreamble.tex" );
376 :     if ( defined($tthPreambleFile) ) {
377 :     local(*TTHIN);
378 :     open (TTHIN, "${main::templateDirectory}tthPreamble.tex") || die "Can't open file ${main::templateDirectory}tthPreamble.tex";
379 :     #my @tthPreambleArray = <TTHIN>;
380 :     local($/);
381 :     $/ = undef;
382 :     $tthPreambleContents = <TTHIN>;#join("",@tthPreambleArray);
383 :     close(TTHIN);
384 :    
385 :     $tthPreambleContents =~ s/(.)\n/$1%\n/g; # thanks to Jim Martino
386 :     # each line in the definition file
387 :     # should end with a % to prevent
388 :     # adding supurious paragraphs to output.
389 :    
390 :     $tthPreambleContents .="%\n"; # solves the problem if the file doesn't end with a return.
391 :    
392 :     } else {
393 :     $tthPreambleContents = "";
394 :     }
395 :     }
396 :    
397 :     $inputString = $tthPreambleContents . $inputString;
398 :     $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.
399 :    
400 :     # $tthpath is now taken from $Global::externalTTHPath via %envir.
401 :     my $tthpath = $envir{externalTTHPath};
402 :     my $out;
403 :    
404 :     if (-x $tthpath ) {
405 :     my $tthcmd = "$tthpath -L -f5 -r 2>/dev/null " . $inputString;
406 :     if (open(TTH, "$tthcmd |")) {
407 :     local($/);
408 :     $/ = undef;
409 :     $out = <TTH>;
410 :     $/ = "\n";
411 :     close(TTH);
412 :     }else {
413 :     $out = "<BR>there has been an error in executing $tthcmd<BR>";
414 :     }
415 :     } else {
416 :     $out = "<BR> Can't execute the program tth at |$tthpath|<BR>";
417 :     }
418 :    
419 :     $out;
420 :     }
421 :    
422 :     # ----- ----- ----- -----
423 :    
424 :     =head2 math2img
425 :    
426 :     math2img(texString) - returns an IMG tag pointing to an image version of the supplied TeX
427 :    
428 :     =cut
429 :    
430 :     my $math2imgCount = 0;
431 :    
432 :     sub math2img {
433 :     my $tex = shift;
434 :     my $mode = shift;
435 :    
436 :     my $sourcePath = $envir{templateDirectory} . "/" . $envir{fileName};
437 :     my $tempFile = "m2i/$envir{studentLogin}.$envir{setNumber}.$envir{probNum}."
438 :     . $math2imgCount++ . ".png";
439 :     my $tempPath = surePathToTmpFile($tempFile); #my $tempPath = "$envir{tempDirectory}$tempFile";
440 :     my $tempURL = "$envir{tempURL}/$tempFile";
441 :    
442 :     my $forceRefresh = $envir{refreshMath2img};
443 :     my $imageMissing = not -e $tempPath;
444 :     my $imageStale = (stat $sourcePath)[9] > (stat $tempPath)[9];
445 :     if ($forceRefresh or $imageMissing or $imageStale) {
446 :     # image file doesn't exist, or source file is newer then image file
447 :     #warn "math2img: refreshMath2img forcing image generation for $tempFile\n" if $forceRefresh;
448 :     #warn "math2img: $tempFile doesn't exist, so generating it\n" if $imageMissing;
449 :     #warn "math2img: source file (", (stat $sourcePath)[9], ") is newer than image file (",
450 :     # (stat $tempPath)[9], ") so re-generating image\n" if $imageStale;
451 :     if (-e tempPath) {
452 :     unlink $tempPath or die "Failed to delete stale math2img file $tempPath: $!";
453 :     }
454 :     dvipng(
455 :     $envir{dvipngTempDir}, $envir{externalLaTeXPath},
456 :     $envir{externalDvipngPath}, $tex, $tempPath
457 :     );
458 :     }
459 :    
460 :     if (-e $tempPath) {
461 :     return "<img align=\"middle\" src=\"$tempURL\" alt=\"$tex\">" if $mode eq "inline";
462 :     return "<div align=\"center\"><img src=\"$tempURL\" alt=\"$tex\"></div>" if $mode eq "display";
463 :     } else {
464 :     return "<b>[math2img failed]</b>";
465 :     # it might be nice to call tth here as a fallback instead:
466 :     #return tth($tex);
467 :     }
468 :     };
469 :    
470 :     ## dvipngTempDir externalLaTeXPath, externalDvipngPath
471 :     #sub dvipng {
472 :     # my ($tex, $targetPath) = @_;
473 :     #
474 :     # # create a temporary directory for tex to shit in
475 :     # my $wd = $envir{dvipngTempDir};
476 :     # my $texFile = "$wd/equation.tex";
477 :     # my $dviFile = "$wd/equation.dvi";
478 :     # my $dviFile2 = "$wd/equationequation.dvi";
479 :     # my $dviCall = "equation";
480 :     # my $pngFile = "$wd/equation1.png";
481 :     #
482 :     # die "dvipng working directory $wd doesn't exist -- caller should have created it for us!\n"
483 :     # unless -e $wd;
484 :     #
485 :     # # write the tex file
486 :     # local *TEX;
487 :     # open TEX, ">", $texFile;
488 :     # print TEX <<'EOF';
489 :     #% BEGIN HEADER
490 :     #\batchmode
491 :     #\documentclass[12pt]{article}
492 :     #\usepackage{amsmath,amsfonts,amssymb}
493 :     #\def\gt{>}
494 :     #\def\lt{<}
495 :     #\usepackage[active,textmath,displaymath]{preview}
496 :     #\begin{document}
497 :     #% END HEADER
498 :     #EOF
499 :     # print TEX "\\( \\displaystyle{$tex} \\)\n";
500 :     # print TEX <<'EOF';
501 :     #% BEGIN FOOTER
502 :     #\end{document}
503 :     #% END FOOTER
504 :     #EOF
505 :     # close TEX;
506 :     #
507 :     # # call latex
508 :     # my $latex = $envir{externalLaTeXPath};
509 :     # system "cd $wd && $latex $texFile";
510 :     #
511 :     # return 0 unless -e $dviFile;
512 :     #
513 :     # # change the name of the DVI file to get around dvipng's crackheadedness
514 :     # system "/bin/mv", $dviFile, $dviFile2;
515 :     #
516 :     # # call dvipng
517 :     # my $dvipng = $envir{externalDvipngPath};
518 :     # system "cd $wd && $dvipng $dviCall" and die "dvipng:dvipng failed: $!";
519 :     #
520 :     # return 0 unless -e $pngFile;
521 :     #
522 :     # system "/bin/mv", $pngFile, $targetPath and die "Failed to mv: $!\n";
523 :     #}
524 :    
525 :     # ----- ----- ----- -----
526 :    
527 :     =head2 alias
528 :    
529 :     alias(pathToFile);
530 :     returns A string describing the URL which links to GIF or html file
531 :     (in HTML and Latex2HTML modes).
532 :     or a path to the appropriate eps version of a GIF file
533 :     (TeX Mode)
534 :    
535 :    
536 :    
537 :     C<alias> allows you to refer to auxiliary files which are in a directory along with
538 :     the problem definition. In addition alias creates an eps copy of GIF files when
539 :     downloading hard copy (TeX mode).
540 :    
541 :     As a rule auxiliary files that are used by
542 :     a number of problems in a course should be placed in C<html/gif> or C<html>
543 :     or in a subdirectory of the C<html> directory,
544 :     while auxiliary files which are used in only one problem should be placed in
545 :     the same directory as the problem in order to make the problem more portable.
546 :    
547 :    
548 :    
549 :     =over 4
550 :    
551 :     =item Files in the html subdirectory
552 :    
553 :     B<When not in TeX mode:>
554 :    
555 :     If the file lies under the C<html> subdirectory, then the approriate URL for the file is created.
556 :     Since the C<html> subdirectory is already accessible to the webserver no other changes need to be made.
557 :     The file path for this type of file should be the complete file path. The path should
558 :     start with the prefix defined in $Global:htmlDirectory.
559 :    
560 :     B<When in TeX mode:>
561 :    
562 :    
563 :     GIF files will be translated into an eps file (using system dependent code)
564 :     and placed in the directory C<tmp/eps>. The full path to this file is returned
565 :     for use by TeX in producing the hard copy. (This should work even in a chrooted
566 :     environment.) in producing the hard copy. (This should work even in a chrooted
567 :     environment.)
568 :    
569 :     The conversion is done by a system dependent script
570 :     called C<gif2eps> which should be in the scripts directory
571 :    
572 :     The URL's for the other files are produced as in non-tex mode
573 :     but will of course not be active.
574 :    
575 :     =item Files in the tmp subdirectory
576 :    
577 :     B<When not in TeX mode:>
578 :    
579 :     If the file lies under the C<tmp> subdirectory, then the approriate URL for the file is created.
580 :     Since the C<tmp> subdirectory is already accessible to the webserver no other changes need to be made.
581 :     The file path for this type of file should be the complete file path. The path should
582 :     start with the prefix defined in $Global:tempDirectory.
583 :    
584 :     B<When in TeX mode:>
585 :    
586 :    
587 :     GIF files will be translated into an eps file (using system dependent code)
588 :     and placed in the directory C<tmp/eps>. The full path to this file is returned
589 :     for use by TeX in producing the hard copy. (This should work even in a chrooted
590 :     environment.)
591 :    
592 :     The conversion is done by a system dependent script
593 :     called C<gif2eps> which should be in the scripts directory
594 :    
595 :     The URL's for the other files are produced as in non-tex mode
596 :     but will of course not be active.
597 :    
598 :     =item Files in the course template subdirectory:
599 :    
600 :     B<When not in TeX mode:>
601 :    
602 :     If the file lies under the course templates subdirectory,
603 :     it is assumed to lie in subdirectory rooted in the directory
604 :     containing the problem template file.
605 :     An alias is created under the C<html/tmp/gif> or
606 :     C<html/tmp/html> directory and linked to the original file.
607 :     The file path for this type of file is a relative
608 :     path rooted at the directory containing the problem template file.
609 :    
610 :     B<When in TeX mode:>
611 :    
612 :     GIF files will be translated into an eps file (using system dependent code)
613 :     and placed in the directory C<html/tmp/eps>. The full path to this file is returned
614 :     for use by TeX in producing the hard copy. (This should work even in a chrooted
615 :     environment.)
616 :    
617 :     The conversion is done by a system dependent script
618 :     called C<gif2eps> which should be in the scripts directory
619 :    
620 :     The URL's for the other files are produced as in non-tex mode
621 :     but will of course not be active.
622 :    
623 :     =back
624 :    
625 :     =cut
626 :    
627 :    
628 :    
629 :     # Currently gif, html and types are supported.
630 :     #
631 :     # If the auxiliary file path has not extension then the extension .gif isassumed.
632 :     #
633 :     # If the auxiliary file path leads to a file in the ${Global::htmlDirectory}
634 :     # no changes are made to the file path.
635 :     #
636 :     # If the auxiliary file path is not complete, than it is assumed that it refers
637 :     # to a subdirectoy of the directory containing the problem..
638 :     #
639 :     # The output is either the correct URL for the file
640 :     # or (in TeX mode) the complete path to the eps version of the file
641 :     # and can be used as input into the image macro.
642 :     #
643 :     # surePathToTmpFile takes a path and outputs the complete path:
644 :     # ${main::htmlDirectory}/tmp/path
645 :     # It insures that all of the directories in the path have been created,
646 :     # but does not create the
647 :     # final file.
648 :    
649 :     # For postscript printing, alias generates an eps version of the gif image and places
650 :     # it in the directory eps. This slows down downloading postscript versions somewhat,
651 :     # but not excessivevly.
652 :     # Alias does not do any garbage collection, so files and alias may accumulate and
653 :     # need to be removed manually or by a reaper daemon.
654 :    
655 :    
656 :     # Global variables used:
657 :     # $main::fileName # the full path to the current problem template file
658 :     # $main::htmlDirectory
659 :     # $main::htmlURL
660 :     # $main::tempDirectory
661 :     # $main::tempURL
662 :     # $main::studentLogin
663 :     # $main::psvnNumber
664 :     # $main::setNumber
665 :     # $main::probNum
666 :     # $main::displayMode
667 :    
668 :     # Global macros used
669 :     # gif2eps An external file called by system
670 :     # surePathToTmpFile
671 :     # convertPath
672 :     # directoryFromPath
673 :    
674 :    
675 :     # This subroutine has commands which will not work on non-UNIX environments.
676 :     # system("cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output") &&
677 :    
678 :    
679 :     # local constants $User, $psvn $setNumber $probNum $displayMode
680 :    
681 :     sub sourceAlias {
682 :     my $path_to_file = shift;
683 :     my $user = $main::inputs_ref->{user};
684 :     $user = " " unless defined($user);
685 :     my $out = "source.pl?probSetKey=$main::psvn".
686 :     "&amp;probNum=$main::probNum" .
687 :     "&amp;Mode=$main::displayMode" .
688 :     "&amp;course=". $main::courseName .
689 :     "&amp;user=" . $user .
690 :     "&amp;displayPath=$path_to_file" .
691 :     "&amp;key=". $main::sessionKey;
692 :    
693 :     $out;
694 :     }
695 :    
696 :    
697 :     sub alias {
698 :     # input is a path to the original auxiliary file
699 :     #my $fileName = $main::fileName;
700 :     #my $htmlDirectory = $main::htmlDirectory;
701 :     #my $htmlURL = $main::htmlURL;
702 :     #my $tempDirectory = $main::tempDirectory;
703 :     #my $tempURL = $main::tempURL;
704 :     #my $studentLogin = $main::studentLogin;
705 :     #my $psvnNumber = $main::psvnNumber;
706 :     #my $setNumber = $main::setNumber;
707 :     #my $probNum = $main::probNum;
708 :     #my $displayMode = $main::displayMode;
709 :    
710 :    
711 :     my $aux_file_path = shift @_;
712 :     warn "Empty string used as input into the function alias" unless $aux_file_path;
713 :    
714 :     # problem specific data
715 :     warn "The path to the current problem file template is not defined." unless $main::fileName;
716 :     warn "The current studentLogin is not defined " unless $main::studentLogin;
717 :     warn "The current problem set number is not defined" if $main::setNumber eq ""; # allow for sets equal to 0
718 :     warn "The current problem number is not defined" if $main::probNum eq "";
719 :     warn "The current problem set version number (psvn) is not defined" unless $main::psvnNumber;
720 :     warn "The displayMode is not defined" unless $main::displayMode;
721 :    
722 :     # required macros
723 :     warn "The macro &surePathToTmpFile can't be found" unless defined(&surePathToTmpFile);
724 :     warn "The macro &convertPath can't be found" unless defined(&convertPath);
725 :     warn "The macro &directoryFromPath can't be found" unless defined(&directoryFromPath);
726 :     warn "Can't execute the gif2eps script at ${main::externalGif2EpsPath}" unless ( -x "${main::externalGif2EpsPath}" );
727 :     warn "Can't execute the png2eps script at ${main::externalPng2EpsPath}" unless ( -x "${main::externalPng2EpsPath}" );
728 :    
729 :     # required directory addresses (and URL address)
730 :     warn "htmlDirectory is not defined in $main::htmlDirectory" unless $main::htmlDirectory;
731 :     warn "htmlURL is not defined in \$main::htmlURL" unless $main::htmlURL;
732 :     warn "tempURL is not defined in \$main::tempURL" unless $main::tempURL;
733 :     #warn "The scripts directory is not defined in \$main::scriptDirectory" unless $main::scriptDirectory;
734 :     # with the creation of externalGif2EpsPath and externalPng2EpsPath, the scripts directory is no longer used
735 :    
736 :     # determine extension, if there is one
737 :     # if extension exists, strip and use the value for $ext
738 :     # files without extensions are considered to be picture files:
739 :    
740 :     my $ext;
741 :     if ($aux_file_path =~ s/\.([^\.]*)$// ) {
742 :     $ext = $1;
743 :     } else {
744 :     warn "This file name $aux_file_path did not have an extension.<BR> " .
745 :     "Every file name used as an argument to alias must have an extension.<BR> " .
746 :     "The permissable extensions are .gif, .png, and .html .<BR>";
747 :     $ext = "gif";
748 :     }
749 :    
750 :     # $adr_output is a url in HTML and Latex2HTML modes
751 :     # and a complete path in TEX mode.
752 :     my $adr_output;
753 :    
754 :     # in order to facilitate maintenance of this macro the routines for handling
755 :     # different file types are defined separately. This involves some redundancy
756 :     # in the code but it makes it easier to define special handling for a new file
757 :     # type, (but harder to change the behavior for all of the file types at once
758 :     # (sigh) ).
759 :    
760 :    
761 :     if ($ext eq 'html') {
762 :     ################################################################################
763 :     # .html FILES in HTML, HTML_tth, HTML_dpng, HTML_img and Latex2HTML mode
764 :     ################################################################################
765 :    
766 :     # No changes are made for auxiliary files in the
767 :     # ${Global::htmlDirectory} subtree.
768 :     if ( $aux_file_path =~ m|^$main::tempDirectory| ) {
769 :     $adr_output = $aux_file_path;
770 :     $adr_output =~ s|$main::tempDirectory|$main::tempURL/|;
771 :     $adr_output .= ".$ext";
772 :     } elsif ($aux_file_path =~ m|^$main::htmlDirectory| ) {
773 :     $adr_output = $aux_file_path;
774 :     $adr_output =~ s|$main::htmlDirectory|$main::htmlURL|;
775 :     $adr_output .= ".$ext";
776 :     } else {
777 :     # HTML files not in the htmlDirectory are assumed under live under the
778 :     # templateDirectory in the same directory as the problem.
779 :     # Create an alias file (link) in the directory html/tmp/html which
780 :     # points to the original file and return the URL of this alias.
781 :     # Create all of the subdirectories of html/tmp/html which are needed
782 :     # using sure file to path.
783 :    
784 :     # $fileName is obtained from environment for PGeval
785 :     # it gives the full path to the current problem
786 :     my $filePath = directoryFromPath($main::fileName);
787 :     my $htmlFileSource = convertPath("$main::templateDirectory${filePath}$aux_file_path.html");
788 :     my $link = "html/$main::studentLogin-$main::psvnNumber-set$main::setNumber-prob$main::probNum-$aux_file_path.$ext";
789 :     my $linkPath = surePathToTmpFile($link);
790 :     $adr_output = "${main::tempURL}$link";
791 :     if (-e $htmlFileSource) {
792 :     if (-e $linkPath) {
793 :     unlink($linkPath) || warn "Unable to unlink alias file at |$linkPath|";
794 :     # destroy the old link.
795 :     }
796 :     symlink( $htmlFileSource, $linkPath)
797 :     || warn "The macro alias cannot create a link from |$linkPath| to |$htmlFileSource| <BR>" ;
798 :     } else {
799 :     warn("The macro alias cannot find an HTML file at: |$htmlFileSource|");
800 :     }
801 :     }
802 :     } elsif ($ext eq 'gif') {
803 :     if ( $main::displayMode eq 'HTML' ||
804 :     $main::displayMode eq 'HTML_tth'||
805 :     $main::displayMode eq 'HTML_dpng'||
806 :     $main::displayMode eq 'HTML_img'||
807 :     $main::displayMode eq 'Latex2HTML') {
808 :     ################################################################################
809 :     # .gif FILES in HTML, HTML_tth, HTML_dpng, HTML_img, and Latex2HTML modes
810 :     ################################################################################
811 :    
812 :     #warn "tempDirectory is $main::tempDirectory";
813 :     #warn "file Path for auxiliary file is $aux_file_path";
814 :    
815 :     # No changes are made for auxiliary files in the htmlDirectory or in the tempDirectory subtree.
816 :     if ( $aux_file_path =~ m|^$main::tempDirectory| ) {
817 :     $adr_output = $aux_file_path;
818 :     $adr_output =~ s|$main::tempDirectory|$main::tempURL|;
819 :     $adr_output .= ".$ext";
820 :     #warn "adress out is $adr_output";
821 :     } elsif ($aux_file_path =~ m|^$main::htmlDirectory| ) {
822 :     $adr_output = $aux_file_path;
823 :     $adr_output =~ s|$main::htmlDirectory|$main::htmlURL|;
824 :     $adr_output .= ".$ext";
825 :     } else {
826 :     # files not in the htmlDirectory sub tree are assumed to live under the templateDirectory
827 :     # subtree in the same directory as the problem.
828 :    
829 :     # For a gif file the alias macro creates an alias under the html/images directory
830 :     # which points to the gif file in the problem directory.
831 :     # All of the subdirectories of html/tmp/gif which are needed are also created.
832 :     my $filePath = directoryFromPath($main::fileName);
833 :    
834 :     # $fileName is obtained from environment for PGeval
835 :     # it gives the full path to the current problem
836 :     my $gifSourceFile = convertPath("$main::templateDirectory${filePath}$aux_file_path.gif");
837 :     #my $link = "gif/$main::studentLogin-$main::psvnNumber-set$main::setNumber-prob$main::probNum-$aux_file_path.$ext";
838 :     my $link = "gif/$main::setNumber-prob$main::probNum-$aux_file_path.$ext";
839 :    
840 :     my $linkPath = surePathToTmpFile($link);
841 :     $adr_output = "${main::tempURL}$link";
842 :     #warn "linkPath is $linkPath";
843 :     #warn "adr_output is $adr_output";
844 :     if (-e $gifSourceFile) {
845 :     if (-e $linkPath) {
846 :     unlink($linkPath) || warn "Unable to unlink old alias file at $linkPath";
847 :     }
848 :     symlink($gifSourceFile, $linkPath)
849 :     || warn "The macro alias cannot create a link from |$linkPath| to |$gifSourceFile| <BR>" ;
850 :     } else {
851 :     warn("The macro alias cannot find a GIF file at: |$gifSourceFile|");
852 :     }
853 :     }
854 :     } elsif ($main::displayMode eq 'TeX') {
855 :     ################################################################################
856 :     # .gif FILES in TeX mode
857 :     ################################################################################
858 :    
859 :     if ($envir{texDisposition} eq "pdf") {
860 :     # We're going to create PDF files with our TeX (using pdflatex), so we
861 :     # need images in PNG format.
862 :    
863 :     my $gifFilePath;
864 :    
865 :     if ($aux_file_path =~ m/^$main::htmlDirectory/ or $aux_file_path =~ m/^$main::tempDirectory/) {
866 :     # we've got a full pathname to a file
867 :     $gifFilePath = "$aux_file_path.gif";
868 :     } else {
869 :     # we assume the file is in the same directory as the problem source file
870 :     $gifFilePath = $main::templateDirectory . directoryFromPath($main::fileName) . "$aux_file_path.gif";
871 :     }
872 :    
873 :     my $gifFileName = fileFromPath($gifFilePath);
874 :    
875 :     $gifFileName =~ /^(.*)\.gif$/;
876 :     my $pngFilePath = surePathToTmpFile("$main::tempDirectory/png/$1.png");
877 :     my $returnCode = system "$envir{externalGif2PngPath} $gifFilePath $pngFilePath";
878 :    
879 :     if ($returnCode or not -e $pngFilePath) {
880 :     die "failed to convert gif->png with $envir{externalGif2PngPath}: $!\n";
881 :     }
882 :    
883 :     $adr_output = $pngFilePath;
884 :     } else {
885 :     # Since we're not creating PDF files, we're probably just using a plain
886 :     # vanilla latex. Hence, we need EPS images.
887 :    
888 :     ################################################################################
889 :     # This is statement used below is system dependent.
890 :     # Notice that the range of colors is restricted when converting to postscript to keep the files small
891 :     # "cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmtops -noturn > $adr_output"
892 :     # "cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn > $adr_output"
893 :     ################################################################################
894 :     if ($aux_file_path =~ m|^$main::htmlDirectory| or $aux_file_path =~ m|^$main::tempDirectory|) {
895 :     # To serve an eps file copy an eps version of the gif file to the subdirectory of eps/
896 :     my $linkPath = directoryFromPath($main::fileName);
897 :    
898 :     my $gifSourceFile = "$aux_file_path.gif";
899 :     my $gifFileName = fileFromPath($gifSourceFile);
900 :     $adr_output = surePathToTmpFile("$main::tempDirectory/eps/$main::studentLogin-$main::psvnNumber-$gifFileName.eps") ;
901 :    
902 :     if (-e $gifSourceFile) {
903 :     #system("cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output")
904 :     system("${main::externalGif2EpsPath} $gifSourceFile $adr_output" )
905 :     && die "Unable to create eps file:\n |$adr_output| from file\n |$gifSourceFile|\n in problem $main::probNum " .
906 :     "using the system dependent script\n |${main::externalGif2EpsPath}| \n";
907 :     } else {
908 :     die "|$gifSourceFile| cannot be found. Problem number: |$main::probNum|";
909 :     }
910 :     } else {
911 :     # To serve an eps file copy an eps version of the gif file to a subdirectory of eps/
912 :     my $filePath = directoryFromPath($main::fileName);
913 :     my $gifSourceFile = "${main::templateDirectory}${filePath}$aux_file_path.gif";
914 :     #print "content-type: text/plain \n\nfileName = $fileName and aux_file_path =$aux_file_path<BR>";
915 :     $adr_output = surePathToTmpFile("eps/$main::studentLogin-$main::psvnNumber-set$main::setNumber-prob$main::probNum-$aux_file_path.eps");
916 :    
917 :     if (-e $gifSourceFile) {
918 :     #system("cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output") &&
919 :     #warn "Unable to create eps file: |$adr_output|\n from file\n |$gifSourceFile|\n in problem $main::probNum";
920 :     #warn "Help ${main::externalGif2EpsPath}" unless -x "${main::externalGif2EpsPath}";
921 :     system("${main::externalGif2EpsPath} $gifSourceFile $adr_output" )
922 :     && die "Unable to create eps file:\n |$adr_output| from file\n |$gifSourceFile|\n in problem $main::probNum " .
923 :     "using the system dependent script\n |${main::externalGif2EpsPath}| \n ";
924 :     } else {
925 :     die "|$gifSourceFile| cannot be found. Problem number: |$main::probNum|";
926 :     }
927 :     }
928 :     }
929 :     } else {
930 :     wwerror("Error in alias: dangerousMacros.pl","unrecognizable displayMode = $main::displayMode","");
931 :     }
932 :     } elsif ($ext eq 'png') {
933 :     if ( $main::displayMode eq 'HTML' ||
934 :     $main::displayMode eq 'HTML_tth'||
935 :     $main::displayMode eq 'HTML_dpng'||
936 :     $main::displayMode eq 'HTML_img'||
937 :     $main::displayMode eq 'Latex2HTML') {
938 :     ################################################################################
939 :     # .png FILES in HTML, HTML_tth, HTML_dpng, HTML_img, and Latex2HTML modes
940 :     ################################################################################
941 :    
942 :     #warn "tempDirectory is $main::tempDirectory";
943 :     #warn "file Path for auxiliary file is $aux_file_path";
944 :    
945 :     # No changes are made for auxiliary files in the htmlDirectory or in the tempDirectory subtree.
946 :     if ( $aux_file_path =~ m|^$main::tempDirectory| ) {
947 :     $adr_output = $aux_file_path;
948 :     $adr_output =~ s|$main::tempDirectory|$main::tempURL|;
949 :     $adr_output .= ".$ext";
950 :     #warn "adress out is $adr_output";
951 :     } elsif ($aux_file_path =~ m|^$main::htmlDirectory| ) {
952 :     $adr_output = $aux_file_path;
953 :     $adr_output =~ s|$main::htmlDirectory|$main::htmlURL|;
954 :     $adr_output .= ".$ext";
955 :     } else {
956 :     # files not in the htmlDirectory sub tree are assumed to live under the templateDirectory
957 :     # subtree in the same directory as the problem.
958 :    
959 :     # For a png file the alias macro creates an alias under the html/images directory
960 :     # which points to the png file in the problem directory.
961 :     # All of the subdirectories of html/tmp/gif which are needed are also created.
962 :     my $filePath = directoryFromPath($main::fileName);
963 :    
964 :     # $fileName is obtained from environment for PGeval
965 :     # it gives the full path to the current problem
966 :     my $pngSourceFile = convertPath("$main::templateDirectory${filePath}$aux_file_path.png");
967 :     my $link = "gif/$main::studentLogin-$main::psvnNumber-set$main::setNumber-prob$main::probNum-$aux_file_path.$ext";
968 :     my $linkPath = surePathToTmpFile($link);
969 :     $adr_output = "${main::tempURL}$link";
970 :     #warn "linkPath is $linkPath";
971 :     #warn "adr_output is $adr_output";
972 :     if (-e $pngSourceFile) {
973 :     if (-e $linkPath) {
974 :     unlink($linkPath) || warn "Unable to unlink old alias file at $linkPath";
975 :     }
976 :     symlink($pngSourceFile, $linkPath)
977 :     || warn "The macro alias cannot create a link from |$linkPath| to |$pngSourceFile| <BR>" ;
978 :     } else {
979 :     warn("The macro alias cannot find a PNG file at: |$pngSourceFile|");
980 :     }
981 :     }
982 :     } elsif ($main::displayMode eq 'TeX') {
983 :     ################################################################################
984 :     # .png FILES in TeX mode
985 :     ################################################################################
986 :    
987 :     if ($envir{texDisposition} eq "pdf") {
988 :     # We're going to create PDF files with our TeX (using pdflatex), so we
989 :     # need images in PNG format. what luck! they're already in PDF format!
990 :    
991 :     my $pngFilePath;
992 :    
993 :     if ($aux_file_path =~ m/^$main::htmlDirectory/ or $aux_file_path =~ m/^$main::tempDirectory/) {
994 :     # we've got a full pathname to a file
995 :     $pngFilePath = "$aux_file_path.png";
996 :     } else {
997 :     # we assume the file is in the same directory as the problem source file
998 :     $pngFilePath = $main::templateDirectory . directoryFromPath($main::fileName) . "$aux_file_path.png";
999 :     }
1000 :    
1001 :     $adr_output = $pngFilePath;
1002 :     } else {
1003 :     # Since we're not creating PDF files, we're probably just using a plain
1004 :     # vanilla latex. Hence, we need EPS images.
1005 :    
1006 :     ################################################################################
1007 :     # This is statement used below is system dependent.
1008 :     # Notice that the range of colors is restricted when converting to postscript to keep the files small
1009 :     # "cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmtops -noturn > $adr_output"
1010 :     # "cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn > $adr_output"
1011 :     ################################################################################
1012 :    
1013 :     if ($aux_file_path =~ m|^$main::htmlDirectory| or $aux_file_path =~ m|^$main::tempDirectory|) {
1014 :     # To serve an eps file copy an eps version of the png file to the subdirectory of eps/
1015 :     my $linkPath = directoryFromPath($main::fileName);
1016 :    
1017 :     my $pngSourceFile = "$aux_file_path.png";
1018 :     my $pngFileName = fileFromPath($pngSourceFile);
1019 :     $adr_output = surePathToTmpFile("$main::tempDirectory/eps/$main::studentLogin-$main::psvnNumber-$pngFileName.eps") ;
1020 :    
1021 :     if (-e $pngSourceFile) {
1022 :     #system("cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output")
1023 :     system("${main::externalPng2EpsPath} $pngSourceFile $adr_output" )
1024 :     && die "Unable to create eps file:\n |$adr_output| from file\n |$pngSourceFile|\n in problem $main::probNum " .
1025 :     "using the system dependent script\n |${main::externalPng2EpsPath}| \n";
1026 :     } else {
1027 :     die "|$pngSourceFile| cannot be found. Problem number: |$main::probNum|";
1028 :     }
1029 :     } else {
1030 :     # To serve an eps file copy an eps version of the png file to a subdirectory of eps/
1031 :     my $filePath = directoryFromPath($main::fileName);
1032 :     my $pngSourceFile = "${main::templateDirectory}${filePath}$aux_file_path.png";
1033 :     #print "content-type: text/plain \n\nfileName = $fileName and aux_file_path =$aux_file_path<BR>";
1034 :     $adr_output = surePathToTmpFile("eps/$main::studentLogin-$main::psvnNumber-set$main::setNumber-prob$main::probNum-$aux_file_path.eps") ;
1035 :     if (-e $pngSourceFile) {
1036 :     #system("cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output") &&
1037 :     #warn "Unable to create eps file: |$adr_output|\n from file\n |$pngSourceFile|\n in problem $main::probNum";
1038 :     #warn "Help ${main::externalPng2EpsPath}" unless -x "${main::externalPng2EpsPath}";
1039 :     system("${main::externalPng2EpsPath} $pngSourceFile $adr_output" )
1040 :     && die "Unable to create eps file:\n |$adr_output| from file\n |$pngSourceFile|\n in problem $main::probNum " .
1041 :     "using the system dependent script\n |${main::externalPng2EpsPath}| \n ";
1042 :     } else {
1043 :     die "|$pngSourceFile| cannot be found. Problem number: |$main::probNum|";
1044 :     }
1045 :     }
1046 :     }
1047 :     } else {
1048 :     wwerror("Error in alias: dangerousMacros.pl","unrecognizable displayMode = $main::displayMode","");
1049 :     }
1050 :     } else { # $ext is not recognized
1051 :     ################################################################################
1052 :     # FILES with unrecognized file extensions in any display modes
1053 :     ################################################################################
1054 :    
1055 :     warn "Error in the macro alias. Alias does not understand how to process files with extension $ext. (Path ot problem file is $main::fileName) ";
1056 :     }
1057 :    
1058 :     warn "The macro alias was unable to form a URL for some auxiliary file used in this problem." unless $adr_output;
1059 :     return $adr_output;
1060 :     }
1061 :    
1062 :    
1063 :    
1064 :    
1065 :    
1066 :     # Experiments
1067 :    
1068 :     # It is important that these subroutines using sort are evaluated before
1069 :     # the problem template is evaluated.
1070 :     # Once the problem template has a "my $a;" susequent sort routines will not work.
1071 :     #
1072 :     # PGsort can be used as a slightly slower but safer sort within problems.
1073 :    
1074 :    
1075 :    
1076 :     =head2 PGsort
1077 :    
1078 :     Because of the way sort is optimized in Perl, the symbols $a and $b
1079 :     have special significance.
1080 :    
1081 :     C<sort {$a<=>$b} @list>
1082 :     C<sort {$a cmp $b} @list>
1083 :    
1084 :     sorts the list numerically and lexically respectively.
1085 :    
1086 :     If C<my $a;> is used in a problem, before the sort routine is defined in a macro, then
1087 :     things get badly confused. To correct this, the following macros are defined in
1088 :     dangerougMacros.pl which is evaluated before the problem template is read.
1089 :    
1090 :     PGsort sub { $_[0] <=> $_[1] }, @list;
1091 :     PGsort sub { $_[0] cmp $_[1] }, @list;
1092 :    
1093 :     provide slightly slower, but safer, routines for the PG language. (The subroutines
1094 :     for ordering are B<required>. Note the commas!)
1095 :    
1096 :     =cut
1097 :    
1098 :    
1099 :    
1100 :     # sub PGsort {
1101 :     # my $sort_order = shift;
1102 :     # die "Must supply an ordering function with PGsort: PGsort sub {\$a cmp \$b }, \@list\n" unless ref($sort_order) eq 'CODE';
1103 :     # sort {&$sort_order($a,$b)} @_;
1104 :     # }
1105 :     # Moved to translate.pl
1106 :     # For some reason it still caused
1107 :     # trouble here when there was
1108 :     # more than one ans_eval in ANS()
1109 :     # No-one knows why?
1110 :    
1111 :     # This allows the use of i for imaginary numbers
1112 :     # one can write 3 +2i rather than 3+2i()
1113 :     #
1114 :    
1115 :     sub i;
1116 :    
1117 :     1; # required to load properly

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9