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