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