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