[system] / trunk / pg / macros / dangerousMacros.pl Repository: Repository Listing bbplugincoursesdistsnplrochestersystemwww

# View of /trunk/pg/macros/dangerousMacros.pl

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


 aubreyja at gmail dot com ViewVC Help Powered by ViewVC 1.0.9