Parent Directory
|
Revision Log
major update which adds objective methods to the basic code of PG. HEAD should be considered more beta than usual for a few days until minor glitches are shaken out. new modules needed: PGcore PGalias PGresource PGloadfiles PGanswergroup PGresponsegroup Tie::IxHash dangerousMacros.pl is no longer used.
1 ################################################################################ 2 # WeBWorK Online Homework Delivery System 3 # Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ 4 # $CVSHeader: pg/macros/dangerousMacros.pl,v 1.58 2009/11/04 17:54:42 dpvc Exp $ 5 # 6 # This program is free software; you can redistribute it and/or modify it under 7 # the terms of either: (a) the GNU General Public License as published by the 8 # Free Software Foundation; either version 2, or (at your option) any later 9 # version, or (b) the "Artistic License" which comes with this package. 10 # 11 # This program is distributed in the hope that it will be useful, but WITHOUT 12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 # FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the 14 # Artistic License for more details. 15 ################################################################################ 16 17 =head1 NAME 18 19 dangerousMacros.pl - Macros which require elevated permissions to execute. 20 21 =head1 SYNPOSIS 22 23 loadMacros(macrofile1,macrofile2,...) 24 25 insertGraph(graphObject); # returns a path to the file containing the graph image. 26 27 tth(texString); # returns an HTML version of the tex code passed to it. 28 29 alias(pathToFile); # returns URL which links to that file 30 31 =head1 DESCRIPTION 32 33 dangerousMacros.pl contains macros that use potentially dangerous functions like 34 require and eval. They can reference disk files for reading and writing, create 35 links, and execute commands. It may be necessary to modify certain addresses in 36 this file to make the scripts run properly in different environments. 37 38 This file is loaded implicitly every time a new problem is rendered. 39 40 =for comment 41 42 FIXME this information belongs in global.conf where modules to load are listed. 43 I don't see why this shows up here. 44 45 =head2 Sharing modules 46 47 Most modules are loaded by dangerousMacros.pl 48 49 The modules must be loaded using require (not use) since the 50 courseScriptsDirectory is defined at run time. 51 52 The following considerations come into play. 53 54 =over 55 56 =item * 57 58 One needs to limit the access to modules for safety -- hence only modules in the 59 F<courseScriptsDirectory> can be loaded. 60 61 =item * 62 63 Loading them in dangerousMacros.pl is wasteful, since the modules would need to 64 be reloaded everytime a new safe compartment is created. (I believe that using 65 require takes care of this.) 66 67 =item * 68 69 Loading GD within a safeCompartment creates infinite recurrsion in AUTOLOAD 70 (probably a bug) hence this module is loaded by translate.pl and then shared 71 with the safe compartment. 72 73 =item * 74 75 Other modules loaded by translate.pl are C<Exporter> and C<DynaLoader>. 76 77 =item * 78 79 PGrandom is loaded by F<PG.pl>, since it is needed there. 80 81 =back 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 # BEGIN { 97 # be_strict(); # an alias for use strict. This means that all global variable must contain main:: as a prefix. 98 # 99 # } 100 # 101 # # ^variable my $debugON 102 # my $debugON = 0; 103 # 104 # # grab read only variables from the current safe compartment 105 # 106 # # ^variable my $macrosPath 107 # my ($macrosPath, 108 # # ^variable my $pwd 109 # $pwd, 110 # # ^variable my $appletPath 111 # $appletPath, 112 # # ^variable my $server_root_url 113 # $server_root_url, 114 # # ^variable my $templateDirectory 115 # $templateDirectory, 116 # # ^variable my $scriptDirectory 117 # $scriptDirectory, 118 # # ^variable my $externalTTHPath 119 # $externalTTHPath, 120 # ); 121 # 122 # # ^function _dangerousMacros_init 123 # # ^uses %envir 124 # # ^uses $macrosPath 125 # # ^uses $pwd 126 # # ^uses $appletPath 127 # # ^uses $server_root_url 128 # # ^uses $templateDirectory 129 # # ^uses $scriptDirectory 130 # # ^uses $externalTTHPath 131 # # ^uses $debugON 132 133 sub _dangerousMacros_init { #use envir instead of local variables? 134 # # will allow easy addition of new directories -- is this too liberal? do some pg directories need to be protected? 135 # $macrosPath = eval('$main::envir{pgDirectories}{macrosPath}'); 136 # # will allow easy addition of new directories -- is this too liberal? do some pg directories need to be protected? 137 # $pwd = eval('$main::envir{fileName}'); $pwd =~ s!/[^/]*$!!; 138 # $appletPath = eval('$main::envir{pgDirectories}{appletPath}'); 139 # $server_root_url = eval('$main::envir{server_root_url}'); 140 # 141 # $templateDirectory = eval('$main::envir{templateDirectory}'); 142 # $scriptDirectory = eval('$main::envir{scriptDirectory}'); 143 # $externalTTHPath = eval('$main::envir{externalTTHPath}'); 144 # $pwd = $templateDirectory.$pwd unless substr($pwd,0,1) eq '/'; 145 # $pwd =~ s!/tmpEdit/!/!; 146 # warn "dangerousmacros initialized" if $debugON; 147 # warn eval(q! "dangerousmacros.pl externalTTHPath is ".$main::externalTTHPath;!) if $debugON; 148 # warn eval(q! "dangerousmacros.pl: The envir variable $main::{envir} is".join(" ",%main::envir)!) if $debugON; 149 150 } 151 152 # 153 # # ^function _dangerousMacros_export 154 # sub _dangerousMacros_export { 155 # my @EXPORT= ( 156 # '&_dangerousMacros_init', 157 # '&alias', 158 # '&compile_file', 159 # '&insertGraph', 160 # '&loadMacros', 161 # '&HEADER_TEXT', 162 # '&sourceAlias', 163 # '&tth', 164 # ); 165 # @EXPORT; 166 # } 167 # 168 # 169 # =head2 loadMacros 170 # 171 # loadMacros(@macroFiles) 172 # 173 # loadMacros takes a list of file names and evaluates the contents of each file. 174 # This is used to load macros which define and augment the PG language. The macro 175 # files are searched for in the directories specified by the array referenced by 176 # $macrosPath, which by default is the current course's macros directory followed 177 # by WeBWorK's pg/macros directory. The latter is where the default behaviour of 178 # the PG language is defined. The default path is set in the global.conf file. 179 # 180 # Macro files named PG.pl, IO.pl, or dangerousMacros.pl will be loaded with no 181 # opcode restrictions, hence any code in those files will be able to execute 182 # privileged operations. This is true no matter which macro directory the file is 183 # in. For example, if $macrosPath contains the path to a problem library macros 184 # directory which contains a PG.pl file, this file will be loaded and allowed to 185 # engage in privileged behavior. 186 # 187 # =head3 Overloading macro files 188 # 189 # An individual course can modify the PG language, for that course only, by 190 # duplicating one of the macro files in the system-wide macros directory and 191 # placing this file in the macros directory for the course. The new file in the 192 # course's macros directory will now be used instead of the file in the 193 # system-wide macros directory. 194 # 195 # The new file in the course macros directory can by modified by adding macros or 196 # modifying existing macros. 197 # 198 # =head3 Modifying existing macros 199 # 200 # I<Modifying macros is for users with some experience.> 201 # 202 # Modifying existing macros might break other standard macros or problems which 203 # depend on the unmodified behavior of these macors so do this with great caution. 204 # In addition problems which use new macros defined in these files or which depend 205 # on the modified behavior of existing macros will not work in other courses 206 # unless the macros are also transferred to the new course. It helps to document 207 # the problems by indicating any special macros which the problems require. 208 # 209 # There is no facility for modifying or overloading a single macro. The entire 210 # file containing the macro must be overloaded. 211 # 212 # Modifications to files in the course macros directory affect only that course, 213 # they will not interfere with the normal behavior of WeBWorK in other courses. 214 # 215 # =cut 216 # 217 # # Global variables used 218 # # ${main::macrosPath} 219 # # Global macros used 220 # # None 221 # 222 # # Because of the need to use the directory variables it is tricky to define this 223 # # in translate.pl since, as currently written, the directories are not available 224 # # at that time. Perhaps if I rewrite translate as an object that method will work. 225 # 226 # # The only difficulty with defining loadMacros inside the Safe compartment is that 227 # # the error reporting does not work with syntax errors. 228 # # A kludge using require works around this problem 229 # 230 # 231 # # ^function loadMacros 232 # # ^uses time_it 233 # # ^uses $debugON 234 # # ^uses $externalTTHPath 235 # # ^uses findMacroFile 236 # sub loadMacros { 237 # my @files = @_; 238 # my $fileName; 239 # eval {main::time_it("begin load macros");}; 240 # ############################################################################### 241 # # At this point the directories have been defined from %envir and we can define 242 # # the directories for this file 243 # ############################################################################### 244 # 245 # # special case inits 246 # foreach my $file ('PG.pl','dangerousMacros.pl','IO.pl') { 247 # my $macro_file_name = $file; 248 # $macro_file_name =~s/\.pl//; # trim off the extension 249 # $macro_file_name =~s/\.pg//; # sometimes the extension is .pg (e.g. CAPA files) 250 # my $init_subroutine_name = "_${macro_file_name}_init"; 251 # my $init_subroutine = eval { \&{$init_subroutine_name} }; 252 # use strict; 253 # my $macro_file_loaded = defined($init_subroutine); 254 # warn "dangerousMacros: macro init $init_subroutine_name defined |$init_subroutine| |$macro_file_loaded|" if $debugON; 255 # if ( defined($init_subroutine) && defined( &{$init_subroutine} ) ) { 256 # 257 # warn "dangerousMacros: initializing $macro_file_name" if $debugON; 258 # &$init_subroutine(); 259 # } 260 # } 261 # unless (defined( $externalTTHPath)){ 262 # warn "WARNING::Please make sure that the DOCUMENT() statement comes before<BR>\n" . 263 # " the loadMacros() statement in the problem template.<p>" . 264 # " The externalTTHPath variable |$externalTTHPath| was\n". 265 # " not defined which usually indicates the problem above.<br>\n"; 266 # 267 # } 268 # #warn "running load macros"; 269 # while (@files) { 270 # $fileName = shift @files; 271 # next if ($fileName =~ /^PG.pl$/) ; # the PG.pl macro package is already loaded. 272 # 273 # my $macro_file_name = $fileName; 274 # $macro_file_name =~s/\.pl//; # trim off the extension 275 # $macro_file_name =~s/\.pg//; # sometimes the extension is .pg (e.g. CAPA files) 276 # my $init_subroutine_name = "_${macro_file_name}_init"; 277 # $init_subroutine_name =~ s![^a-zA-Z0-9_]!_!g; # remove dangerous chars 278 # 279 # ############################################################################### 280 # # For some reason the "no stict" which works on webwork-db doesn't work on 281 # # webwork. For this reason the constuction &{$init_subroutine_name} 282 # # was abandoned and replaced by eval. This is considerably more dangerous 283 # # since one could hide something nasty in a file name. 284 # # Keep an eye on this ??? 285 # # webwork-db used perl 5.6.1 and webwork used perl 5.6.0 286 # ############################################################################### 287 # 288 # # compile initialization subroutine. (5.6.0 version) 289 # 290 # 291 # # eval( q{ \$init_subroutine = \\&main::}.$init_subroutine_name); 292 # # warn "dangerousMacros: failed to compile $init_subroutine_name. $@" if $@; 293 # 294 # 295 # ############################################################################### 296 # #compile initialization subroutine. (5.6.1 version) also works with 5.6.0 297 # 298 # # no strict; 299 # my $init_subroutine = eval { \&{'main::'.$init_subroutine_name} }; 300 # # use strict; 301 # 302 # ############################################################################### 303 # 304 # # macros are searched for in the directories listed in the $macrosPath array reference. 305 # 306 # my $macro_file_loaded = defined($init_subroutine) && defined(&$init_subroutine); 307 # warn "dangerousMacros: macro init $init_subroutine_name defined |$init_subroutine| |$macro_file_loaded|" if $debugON; 308 # unless ($macro_file_loaded) { 309 # warn "loadMacros: loading macro file $fileName\n" if $debugON; 310 # my $filePath = findMacroFile($fileName); 311 # #### (check for renamed files here?) #### 312 # if ($filePath) { 313 # compile_file($filePath); 314 # #warn "loadMacros is compiling $filePath\n"; 315 # } 316 # else { 317 # die "Can't locate macro file |$fileName| via path: |".join("|, |",@{$macrosPath})."|"; 318 # } 319 # } 320 # ############################################################################### 321 # # Try again to define the initialization subroutine. (5.6.0 version) 322 # 323 # # eval( q{ \$init_subroutine = \\&main::}.$init_subroutine_name ); 324 # # warn "dangerousMacros: failed to compile $init_subroutine_name. $@" if $@; 325 # # $init_subroutine = $temp::rf_init_subroutine; 326 # ############################################################################### 327 # # Try again to define the initialization subroutine. (5.6.1 version) also works with 5.6.0 328 # 329 # # no strict; 330 # $init_subroutine = eval { \&{'main::'.$init_subroutine_name} }; 331 # # use strict; 332 # ############################################################################### 333 # #warn "loadMacros: defining \$temp::rf_init_subroutine ",$temp::rf_init_subroutine; 334 # $macro_file_loaded = defined($init_subroutine) && defined(&$init_subroutine); 335 # warn "dangerousMacros: macro init $init_subroutine_name defined |$init_subroutine| |$macro_file_loaded|" if $debugON; 336 # 337 # if ( defined($init_subroutine) && defined( &{$init_subroutine} ) ) { 338 # warn "dangerousMacros: initializing $macro_file_name" if $debugON; 339 # &$init_subroutine(); 340 # } 341 # #warn "main:: contains <br>\n $macro_file_name ".join("<br>\n $macro_file_name ", %main::); 342 # } 343 # eval{main::time_it("end load macros");}; 344 # } 345 # 346 # # 347 # # Look for a macro file in the directories specified in the macros path 348 # # 349 # 350 # # ^function findMacroFile 351 # # ^uses $macrosPath 352 # # ^uses $pwd 353 # sub findMacroFile { 354 # my $fileName = shift; 355 # my $filePath; 356 # foreach my $dir (@{$macrosPath}) { 357 # $filePath = "$dir/$fileName"; 358 # $filePath =~ s!^\.\.?/!$pwd/!; 359 # return $filePath if (-r $filePath); 360 # } 361 # return; # no file found 362 # } 363 # 364 # # ^function check_url 365 # # ^uses %envir 366 # sub check_url { 367 # my $url = shift; 368 # return undef if $url =~ /;/; # make sure we can't get a second command in the url 369 # #FIXME -- check for other exploits of the system call 370 # #FIXME -- ALARM feature so that the response cannot be held up for too long. 371 # #FIXME doesn't seem to work with relative addresses. 372 # #FIXME Can we get the machine name of the server? 373 # 374 # my $check_url_command = $envir{externalCheckUrl}; 375 # my $response = system("$check_url_command $url"); 376 # return ($response) ? 0 : 1; # 0 indicates success, 256 is failure possibly more checks can be made 377 # } 378 # 379 # # ^variable our %appletCodebaseLocations 380 # our %appletCodebaseLocations = (); 381 # # ^function findAppletCodebase 382 # # ^uses %appletCodebaseLocations 383 # # ^uses $appletPath 384 # # ^uses $server_root_url 385 # # ^uses check_url 386 # sub findAppletCodebase { 387 # my $fileName = shift; # probably the name of a jar file 388 # return $appletCodebaseLocations{$fileName} #check cache first 389 # if defined($appletCodebaseLocations{$fileName}) 390 # and $appletCodebaseLocations{$fileName} =~/\S/; 391 # 392 # foreach my $appletLocation (@{$appletPath}) { 393 # if ($appletLocation =~ m|^/|) { 394 # $appletLocation = "$server_root_url$appletLocation"; 395 # } 396 # return $appletLocation; # --hack workaround -- just pick the first location and use that -- no checks 397 # #hack to workaround conflict between lwp-request and apache2 398 # # comment out the check_url block 399 # # my $url = "$appletLocation/$fileName"; 400 # # if (check_url($url)) { 401 # # $appletCodebaseLocations{$fileName} = $appletLocation; #update cache 402 # # return $appletLocation # return codebase part of url 403 # # } 404 # } 405 # return "Error: $fileName not found at ". join(", ", @{$appletPath} ); # no file found 406 # } 407 # # errors in compiling macros is not always being reported. 408 # # ^function compile_file 409 # # ^uses @__eval__ 410 # # ^uses PG_restricted_eval 411 # # ^uses $__files__ 412 # sub compile_file { 413 # my $filePath = shift; 414 # warn "loading $filePath" if $debugON; 415 # local(*MACROFILE); 416 # local($/); 417 # $/ = undef; # allows us to treat the file as a single line 418 # open(MACROFILE, "<$filePath") || die "Cannot open file: $filePath"; 419 # my $string = 'BEGIN {push @__eval__, __FILE__};' . "\n" . <MACROFILE>; 420 # my ($result,$error,$fullerror) = &PG_restricted_eval($string); 421 # eval ('$main::__files__->{pop @main::__eval__} = $filePath'); 422 # if ($error) { # the $fullerror report has formatting and is never empty 423 # # this is now handled by PG_errorMessage() in the PG translator 424 # #$fullerror =~ s/\(eval \d+\)/ $filePath\n/; # attempt to insert file name instead of eval number 425 # die "Error detected while loading $filePath:\n$fullerror"; 426 # 427 # } 428 # 429 # close(MACROFILE); 430 # 431 # } 432 # 433 # # This creates on the fly graphs 434 # 435 # =head2 insertGraph 436 # 437 # # returns a path to the file containing the graph image. 438 # $filePath = insertGraph($graphObject); 439 # 440 # insertGraph writes a GIF or PNG image file to the gif subdirectory of the 441 # current course's HTML temp directory. The file name is obtained from the graph 442 # object. Warnings are issued if errors occur while writing to the file. 443 # 444 # Returns a string containing the full path to the temporary file containing the 445 # image. This is most often used in the construct 446 # 447 # TEXT(alias(insertGraph($graph))); 448 # 449 # where alias converts the directory address to a URL when serving HTML pages and 450 # insures that an EPS file is generated when creating TeX code for downloading. 451 # 452 # =cut 453 # 454 # # ^function insertGraph 455 # # ^uses $WWPlot::use_png 456 # # ^uses convertPath 457 # # ^uses surePathToTmpFile 458 # # ^uses PG_restricted_eval 459 # # ^uses $refreshCachedImages 460 # # ^uses $templateDirectory 461 # # ^uses %envir 462 # sub insertGraph { 463 # # Convert the image to GIF and print it on standard output 464 # my $graph = shift; 465 # my $extension = ($WWPlot::use_png) ? '.png' : '.gif'; 466 # my $fileName = $graph->imageName . $extension; 467 # my $filePath = convertPath("gif/$fileName"); 468 # $filePath = &surePathToTmpFile( $filePath ); 469 # my $refreshCachedImages = PG_restricted_eval(q!$refreshCachedImages!); 470 # # Check to see if we already have this graph, or if we have to make it 471 # if( not -e $filePath # does it exist? 472 # or ((stat "$templateDirectory"."$main::envir{fileName}")[9] > (stat $filePath)[9]) # source has changed 473 # or $graph->imageName =~ /Undefined_Set/ # problems from SetMaker and its ilk should always be redone 474 # or $refreshCachedImages 475 # ) { 476 # #createFile($filePath, $main::tmp_file_permission, $main::numericalGroupID); 477 # local(*OUTPUT); # create local file handle so it won't overwrite other open files. 478 # open(OUTPUT, ">$filePath")||warn ("$0","Can't open $filePath<BR>",""); 479 # chmod( 0777, $filePath); 480 # print OUTPUT $graph->draw|| warn("$0","Can't print graph to $filePath<BR>",""); 481 # close(OUTPUT)||warn("$0","Can't close $filePath<BR>",""); 482 # } 483 # $filePath; 484 # } 485 # 486 # =head2 [DEPRECATED] tth 487 # 488 # # returns an HTML version of the TeX code passed to it. 489 # tth($texString); 490 # 491 # This macro sends $texString to the filter program TtH, a TeX to HTML translator 492 # written by Ian Hutchinson. TtH is available free of change non-commerical 493 # use at L<http://hutchinson.belmont.ma.us/tth/>. 494 # 495 # The purpose of TtH is to translate text in the TeX or LaTeX markup language into 496 # HTML markup as best as possible. Some symbols, such as square root symbols are 497 # not translated completely. Macintosh users must use the "MacRoman" encoding 498 # (available in 4.0 and higher browsers) in order to view the symbols correctly. 499 # WeBWorK attempts to force Macintosh browsers to use this encoding when such a 500 # browser is detected. 501 # 502 # The contents of the file F<tthPreamble.tex> in the courses template directory 503 # are prepended to each string. This allows one to define TeX macros which can be 504 # used in every problem. Currently there is no default F<tthPreamble.tex> file, so 505 # if the file is not present in the course template directory no TeX macro 506 # definitions are prepended. TtH already understands most LaTeX commands, but will 507 # not in general know AMS-LaTeX commands. 508 # 509 # This macro contains code which is system dependent and may need to be modified 510 # to run on different systems. 511 # 512 # =cut 513 # 514 # # the contents of this file will not change during problem compilation it 515 # # only needs to be read once. however, the contents of the file may change, 516 # # and indeed the file refered to may change, between rendering passes. thus, 517 # # we need to keep track of the file name and the mtime as well. 518 # # ^variable my $tthPreambleFile 519 # # ^variable my $tthPreambleMtime 520 # # ^variable my $tthPreambleContents 521 # my ($tthPreambleFile, $tthPreambleMtime, $tthPreambleContents); 522 # 523 # # ^function tth 524 # # ^uses $templateDirectory 525 # # ^uses $envir{externalTTHPath} 526 # # ^uses $tthPreambleFile 527 # # ^uses $tthPreambleMtime 528 # # ^uses $tthPreambleContents 529 # sub tth { 530 # my $inputString = shift; 531 # 532 # my $thisFile = "${templateDirectory}tthPreamble.tex" if -r "${templateDirectory}tthPreamble.tex"; 533 # 534 # if (defined $thisFile) { 535 # my $thisMtime = (stat $thisFile)[9]; 536 # my $load = 537 # # load preamble if we haven't loaded it ever 538 # (not defined $tthPreambleFile or not defined $tthPreambleMtime or not defined $tthPreambleContents) 539 # || 540 # # load if the file path has changed 541 # ($tthPreambleFile ne $thisFile) 542 # || 543 # # load if the file has been modified 544 # ($tthPreambleMtime < $thisMtime); 545 # 546 # if ($load) { 547 # local(*TTHIN); 548 # open (TTHIN, "${templateDirectory}tthPreamble.tex") || die "Can't open file ${templateDirectory}tthPreamble.tex"; 549 # local($/); 550 # $/ = undef; 551 # $tthPreambleContents = <TTHIN>; 552 # close(TTHIN); 553 # 554 # $tthPreambleContents =~ s/(.)\n/$1%\n/g; # thanks to Jim Martino 555 # # each line in the definition file 556 # # should end with a % to prevent 557 # # adding supurious paragraphs to output. 558 # 559 # $tthPreambleContents .="%\n"; # solves the problem if the file doesn't end with a return. 560 # } 561 # } else { 562 # $tthPreambleContents = ""; 563 # } 564 # 565 # $inputString = $tthPreambleContents . $inputString; 566 # $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. 567 # 568 # # $tthpath is now taken from $Global::externalTTHPath via %envir. 569 # my $tthpath = $envir{externalTTHPath}; 570 # my $out; 571 # 572 # if (-x $tthpath ) { 573 # my $tthcmd = "$tthpath -L -f5 -u -r 2>/dev/null " . $inputString; 574 # if (open(TTH, "$tthcmd |")) { 575 # local($/); 576 # $/ = undef; 577 # $out = <TTH>; 578 # $/ = "\n"; 579 # close(TTH); 580 # }else { 581 # $out = "<BR>there has been an error in executing $tthcmd<BR>"; 582 # } 583 # } else { 584 # $out = "<BR> Can't execute the program tth at |$tthpath|<BR>"; 585 # } 586 # 587 # $out; 588 # } 589 # 590 # # possible solution to the tth font problem? Works only for iCab. 591 # # ^function symbolConvert 592 # sub symbolConvert { 593 # my $string = shift; 594 # $string =~ s/\x5C/\\/g; #\ 92 \ 595 # $string =~ s/\x7B/\{/g; #{ 123 { 596 # $string =~ s/\x7D/\}/g; #} 125 } 597 # $string =~ s/\xE7/\Á/g; #Á 231 Á 598 # $string =~ s/\xE6/\Ê/g; #Ê 230 Ê 599 # $string =~ s/\xE8/\Ë/g; #Ë 232 Ë 600 # $string =~ s/\xF3/\Û/g; #Û 243 Û 601 # $string =~ s/\xA5/\•/g; #€ 165 • 602 # $string =~ s/\xB2/\≤/g; #¾ 178 ≤ 603 # $string =~ s/\xB3/\≥/g; #„ 179 ≥ 604 # $string =~ s/\xB6/\∂/g; # 182 ∂ 605 # $string =~ s/\xCE/\Œ/g; #‘ 206 Œ 606 # $string =~ s/\xD6/\˜/g; #÷ 214 ˜ 607 # $string =~ s/\xD9/\Ÿ/g; # 217 Ÿ 608 # $string =~ s/\xDA/\⁄/g; #Ž 218 ⁄ 609 # $string =~ s/\xF5/\ı/g; #ž 245 ı 610 # $string =~ s/\xF6/\ˆ/g; #– 246 ˆ 611 # $string =~ s/\xF7/\Á/g; #— 247 Á 612 # $string =~ s/\xF8/\¯/g; #¯ 248 ¯ 613 # $string =~ s/\xF9/\˘/g; #˜ 249 ˘ 614 # $string =~ s/\xFA/\˙/g; #™ 250 ˙ 615 # $string =~ s/\xFB/\˚;/g; #š 251 ˚ 616 # $string; 617 # } 618 # 619 # # ----- ----- ----- ----- 620 # 621 # =head2 [DEPRECATED] math2img 622 # 623 # # returns an IMG tag pointing to an image version of the supplied TeX 624 # math2img($texString); 625 # 626 # This macro was used by the HTML_img display mode, which no longer exists. 627 # 628 # =cut 629 # 630 # # ^variable my $math2imgCount 631 # my $math2imgCount = 0; 632 # 633 # # ^function math2img 634 # # ^uses $math2imgCount 635 # # ^uses $envir{templateDirectory} 636 # # ^uses $envir{fileName} 637 # # ^uses $envir{studentLogin} 638 # # ^uses $envir{setNumber} 639 # # ^uses $envir{probNum} 640 # # ^uses $envir{tempURL} 641 # # ^uses $envir{refreshMath2img} 642 # # ^uses $envir{dvipngTempDir} 643 # # ^uses $envir{externalLaTeXPath} 644 # # ^uses $envir{externalDvipngPath} 645 # sub math2img { 646 # my $tex = shift; 647 # my $mode = shift; 648 # 649 # my $sourcePath = $envir{templateDirectory} . "/" . $envir{fileName}; 650 # my $tempFile = "m2i/$envir{studentLogin}.$envir{setNumber}.$envir{probNum}." 651 # . $math2imgCount++ . ".png"; 652 # my $tempPath = surePathToTmpFile($tempFile); #my $tempPath = "$envir{tempDirectory}$tempFile"; 653 # my $tempURL = "$envir{tempURL}/$tempFile"; 654 # my $forceRefresh = $envir{refreshMath2img}; 655 # my $imageMissing = not -e $tempPath; 656 # my $imageStale = (stat $sourcePath)[9] > (stat $tempPath)[9] if -e $tempPath; 657 # if ($forceRefresh or $imageMissing or $imageStale) { 658 # # image file doesn't exist, or source file is newer then image file 659 # #warn "math2img: refreshMath2img forcing image generation for $tempFile\n" if $forceRefresh; 660 # #warn "math2img: $tempFile doesn't exist, so generating it\n" if $imageMissing; 661 # #warn "math2img: source file (", (stat $sourcePath)[9], ") is newer than image file (", 662 # # (stat $tempPath)[9], ") so re-generating image\n" if $imageStale; 663 # if (-e $tempPath) { 664 # unlink $tempPath or die "Failed to delete stale math2img file $tempPath: $!"; 665 # } 666 # dvipng( 667 # $envir{dvipngTempDir}, $envir{externalLaTeXPath}, 668 # $envir{externalDvipngPath}, $tex, $tempPath 669 # ); 670 # } 671 # 672 # if (-e $tempPath) { 673 # return "<img align=\"middle\" src=\"$tempURL\" alt=\"$tex\">" if $mode eq "inline"; 674 # return "<div align=\"center\"><img src=\"$tempURL\" alt=\"$tex\"></div>" if $mode eq "display"; 675 # } else { 676 # return "<b>[math2img failed]</b>"; 677 # # it might be nice to call tth here as a fallback instead: 678 # #return tth($tex); 679 # } 680 # }; 681 # 682 # =head2 [DEPRECATED] dvipng 683 # 684 # dvipng($working_directory, $latex_path, $dvipng_path, $tex_string, $target_path) 685 # 686 # This macro was used by the HTML_img display mode, which no longer exists. 687 # 688 # =cut 689 # 690 # # copied from IO.pm for backward compatibility with WeBWorK1.8; 691 # # ^function dvipng 692 # sub dvipng($$$$$) { 693 # my ( 694 # $wd, # working directory, for latex and dvipng garbage 695 # # (must already exist!) 696 # $latex, # path to latex binary 697 # $dvipng, # path to dvipng binary 698 # $tex, # tex string representing equation 699 # $targetPath # location of resulting image file 700 # ) = @_; 701 # 702 # my $dvipngBroken = 0; 703 # 704 # my $texFile = "$wd/equation.tex"; 705 # my $dviFile = "$wd/equation.dvi"; 706 # my $dviFile2 = "$wd/equationequation.dvi"; 707 # my $dviCall = "equation"; 708 # my $pngFile = "$wd/equation1.png"; 709 # 710 # unless (-e $wd) { 711 # die "dvipng working directory $wd doesn't exist -- caller should have created it for us!\n"; 712 # return 0; 713 # } 714 # 715 # # write the tex file 716 # local *TEX; 717 # open TEX, ">", $texFile or warn "Failed to create $texFile: $!"; 718 # print TEX <<'EOF'; 719 # % BEGIN HEADER 720 # \batchmode 721 # \documentclass[12pt]{article} 722 # \usepackage{amsmath,amsfonts,amssymb} 723 # \def\gt{>} 724 # \def\lt{<} 725 # \usepackage[active,textmath,displaymath]{preview} 726 # \begin{document} 727 # % END HEADER 728 # EOF 729 # print TEX "\\( \\displaystyle{$tex} \\)\n"; 730 # print TEX <<'EOF'; 731 # % BEGIN FOOTER 732 # \end{document} 733 # % END FOOTER 734 # EOF 735 # close TEX; 736 # 737 # # call latex 738 # system "cd $wd && $latex $texFile > /dev/null" 739 # and warn "Failed to call $latex with $texFile: $!"; 740 # 741 # unless (-e $dviFile) { 742 # warn "Failed to generate DVI file $dviFile"; 743 # return 0; 744 # } 745 # 746 # if ($dvipngBroken) { 747 # # change the name of the DVI file to get around dvipng's 748 # # crackheadedness. This is no longer needed with the newest 749 # # version of dvipng (10 something) 750 # system "/bin/mv", $dviFile, $dviFile2; 751 # } 752 # 753 # # call dvipng -- using warn instead of die passes some extra information 754 # # back to the user the complete warning is still printed in the apache 755 # # error log and a simple message (math2img failed) is returned to the 756 # # webpage. 757 # my $cmdout; 758 # $cmdout = system "cd $wd && $dvipng $dviCall > /dev/null" 759 # and warn "Failed to call$dvipng with $dviCall: $! with signal $cmdout"; 760 # 761 # unless (-e $pngFile) { 762 # warn "Failed to create PNG file $pngFile"; 763 # return 0; 764 # } 765 # 766 # $cmdout = system "/bin/mv", $pngFile, $targetPath and warn "Failed to mv: /bin/mv $pngFile $targetPath $!. Call returned $cmdout. \n"; 767 # } 768 # 769 # ----- ----- ----- ----- 770 # 771 # =head2 alias 772 # 773 # # In HTML modes, returns the URL of a web-friendly version of the specified file. 774 # # In TeX mode, returns the path to a TeX-friendly version of the specified file. 775 # alias($pathToFile); 776 # 777 # alias allows you to refer to auxiliary files which are in a directory along with 778 # the problem definition. In addition alias creates an EPS version of GIF or PNG 779 # files when called in TeX mode. 780 # 781 # As a rule auxiliary files that are used by a number of problems in a course 782 # should be placed in C<html/gif> or C<html> or in a subdirectory of the C<html> 783 # directory, while auxiliary files which are used in only one problem should be 784 # placed in the same directory as the problem in order to make the problem more 785 # portable. 786 # 787 # =head3 Specific behavior of the alias macro 788 # 789 # =head4 Files in the html subdirectory 790 # 791 # =over 792 # 793 # =item When not in TeX mode 794 # 795 # If the file lies under the F<html> subdirectory, then the approriate URL for the 796 # file is returned. Since the F<html> subdirectory is already accessible to the 797 # webserver no other changes need to be made. The file path for this type of file 798 # should be the complete file path. The path should start with the prefix defined 799 # in $courseDirs{html_temp} in global.conf. 800 # 801 # =item When in TeX mode 802 # 803 # GIF and PNG files will be translated into EPS files and placed in the directory 804 # F<tmp/eps>. The full path to this file is returned for use by TeX in producing 805 # the hard copy. The conversion is done by a system dependent commands defined in 806 # F<global.conf> $externalPrograms{gif2eps} (for GIF images) or 807 # $externalPrograms{png2eps} (for PNG images). The URLs for the other files are 808 # produced as in non-TeX mode but will of course not be usable to TeX. 809 # 810 # =back 811 # 812 # =head4 Files in the tmp subdirectory 813 # 814 # =over 815 # 816 # =item When not in TeX mode 817 # 818 # If the file lies under the F<tmp> subdirectory, then the approriate URL for the 819 # file is created. Since the F<tmp> subdirectory is already accessible to the 820 # webserver no other changes need to be made. The file path for this type of file 821 # should be the complete file path. The path should start with the prefix defined 822 # in $courseDirs{html_temp} in global.conf. 823 # 824 # =item When in TeX mode 825 # 826 # GIF and PNG files will be translated into EPS files and placed in the directory 827 # F<tmp/eps>. The full path to this file is returned for use by TeX in producing 828 # the hard copy. The conversion is done by a system dependent commands defined in 829 # F<global.conf> $externalPrograms{gif2eps} (for GIF images) or 830 # $externalPrograms{png2eps} (for PNG images). The URLs for the other files are 831 # produced as in non-TeX mode but will of course not be usable to TeX. 832 # 833 # =back 834 # 835 # =head4 Files in the course template subdirectory 836 # 837 # =over 838 # 839 # =item When not in TeX mode 840 # 841 # If the file lies under the course templates subdirectory, it is assumed to lie 842 # in subdirectory rooted in the directory containing the problem template file. An 843 # alias is created under the F<html/tmp/gif> or F<html/tmp/html> directory and 844 # linked to the original file. The file path for this type of file is a relative 845 # path rooted at the directory containing the problem template file. 846 # 847 # =item When in TeX mode 848 # 849 # GIF and PNG files will be translated into EPS files and placed in the directory 850 # F<tmp/eps>. The full path to this file is returned for use by TeX in producing 851 # the hard copy. The conversion is done by a system dependent commands defined in 852 # F<global.conf> $externalPrograms{gif2eps} (for GIF images) or 853 # $externalPrograms{png2eps} (for PNG images). The URLs for the other files are 854 # produced as in non-TeX mode but will of course not be usable to TeX. 855 # 856 # =back 857 # 858 # =cut 859 # 860 861 # 862 # # Currently gif, html and types are supported. 863 # # 864 # # If the auxiliary file path has not extension then the extension .gif isassumed. 865 # # 866 # # If the auxiliary file path leads to a file in the ${Global::htmlDirectory} 867 # # no changes are made to the file path. 868 # # 869 # # If the auxiliary file path is not complete, than it is assumed that it refers 870 # # to a subdirectoy of the directory containing the problem.. 871 # # 872 # # The output is either the correct URL for the file 873 # # or (in TeX mode) the complete path to the eps version of the file 874 # # and can be used as input into the image macro. 875 # # 876 # # surePathToTmpFile takes a path and outputs the complete path: 877 # # ${main::htmlDirectory}/tmp/path 878 # # It insures that all of the directories in the path have been created, 879 # # but does not create the 880 # # final file. 881 # 882 # # For postscript printing, alias generates an eps version of the gif image and places 883 # # it in the directory eps. This slows down downloading postscript versions somewhat, 884 # # but not excessivevly. 885 # # Alias does not do any garbage collection, so files and alias may accumulate and 886 # # need to be removed manually or by a reaper daemon. 887 # 888 # # This subroutine has commands which will not work on non-UNIX environments. 889 # # system("cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output") && 890 # 891 # # ^function alias 892 # # ^uses %envir 893 # # ^uses $envir{fileName} 894 # # ^uses $envir{htmlDirectory} 895 # # ^uses $envir{htmlURL} 896 # # ^uses $envir{tempDirectory} 897 # # ^uses $envir{tempURL} 898 # # ^uses $envir{studentLogin} 899 # # ^uses $envir{psvnNumber} 900 # # ^uses $envir{setNumber} 901 # # ^uses $envir{probNum} 902 # # ^uses $envir{displayMode} 903 # # ^uses $envir{externalGif2EpsPath} 904 # # ^uses $envir{externalPng2EpsPath} 905 # # ^uses &surePathToTmpFile 906 # # ^uses &convertPath 907 # # ^uses &directoryFromPath 908 # # ^uses &fileFromPath 909 # # ^uses $envir{texDisposition} 910 911 # sub alias { 912 # # input is a path to the original auxiliary file 913 # my $envir = eval(q!\%main::envir!); # get the current root environment 914 # my $fileName = $envir->{fileName}; 915 # my $htmlDirectory = $envir->{htmlDirectory}; 916 # my $htmlURL = $envir->{htmlURL}; 917 # my $tempDirectory = $envir->{tempDirectory}; 918 # my $tempURL = $envir->{tempURL}; 919 # my $studentLogin = $envir->{studentLogin}; 920 # my $psvnNumber = $envir->{psvnNumber}; 921 # my $setNumber = $envir->{setNumber}; 922 # my $probNum = $envir->{probNum}; 923 # my $displayMode = $envir->{displayMode}; 924 # my $externalGif2EpsPath = $envir->{externalGif2EpsPath}; 925 # my $externalPng2EpsPath = $envir->{externalPng2EpsPath}; 926 # 927 # my $aux_file_path = shift @_; 928 # warn "Empty string used as input into the function alias" unless $aux_file_path; 929 # # 930 # # Find auxiliary files even when the main file is in tempates/tmpEdit 931 # # 932 # $fileName =~ s!(^|/)tmpEdit/!\1!; 933 # 934 # # problem specific data 935 # warn "The path to the current problem file template is not defined." unless $fileName; 936 # warn "The current studentLogin is not defined " unless $studentLogin; 937 # warn "The current problem set number is not defined" if $setNumber eq ""; # allow for sets equal to 0 938 # warn "The current problem number is not defined" if $probNum eq ""; 939 # warn "The current problem set version number (psvn) is not defined" unless defined($psvnNumber); 940 # warn "The displayMode is not defined" unless $displayMode; 941 # 942 # # required macros 943 # warn "The macro &surePathToTmpFile can't be found" unless defined(&surePathToTmpFile); 944 # warn "The macro &convertPath can't be found" unless defined(&convertPath); 945 # warn "The macro &directoryFromPath can't be found" unless defined(&directoryFromPath); 946 # # warn "The webwork server does not have permission to execute the gif2eps script at ${externalGif2EpsPath}." unless ( -x "${externalGif2EpsPath}" ); 947 # # warn "The webwork server does not have permission to execute the png2eps script at ${externalPng2EpsPath}." unless ( -x "${externalPng2EpsPath}" ); 948 # 949 # # required directory addresses (and URL address) 950 # warn "htmlDirectory is not defined in $htmlDirectory" unless $htmlDirectory; 951 # warn "htmlURL is not defined in \$htmlURL" unless $htmlURL; 952 # warn "tempURL is not defined in \$tempURL" unless $tempURL; 953 # 954 # # determine extension, if there is one 955 # # if extension exists, strip and use the value for $ext 956 # # files without extensions are considered to be picture files: 957 # 958 # my $ext; 959 # if ($aux_file_path =~ s/\.([^\.]*)$// ) { 960 # $ext = $1; 961 # } else { 962 # warn "This file name $aux_file_path did not have an extension.<BR> " . 963 # "Every file name used as an argument to alias must have an extension.<BR> " . 964 # "The permissable extensions are .gif, .png, and .html .<BR>"; 965 # $ext = "gif"; 966 # } 967 # 968 # # $adr_output is a url in HTML and Latex2HTML modes 969 # # and a complete path in TEX mode. 970 # my $adr_output; 971 # 972 # # in order to facilitate maintenance of this macro the routines for handling 973 # # different file types are defined separately. This involves some redundancy 974 # # in the code but it makes it easier to define special handling for a new file 975 # # type, (but harder to change the behavior for all of the file types at once 976 # # (sigh) ). 977 # 978 # 979 # if ($ext eq 'html') { 980 # ################################################################################ 981 # # .html FILES in HTML, HTML_tth, HTML_dpng, HTML_img, etc. and Latex2HTML mode 982 # ################################################################################ 983 # 984 # # No changes are made for auxiliary files in the 985 # # ${Global::htmlDirectory} subtree. 986 # if ( $aux_file_path =~ m|^$tempDirectory| ) { 987 # $adr_output = $aux_file_path; 988 # $adr_output =~ s|$tempDirectory|$tempURL/|; 989 # $adr_output .= ".$ext"; 990 # } elsif ($aux_file_path =~ m|^$htmlDirectory| ) { 991 # $adr_output = $aux_file_path; 992 # $adr_output =~ s|$htmlDirectory|$htmlURL|; 993 # $adr_output .= ".$ext"; 994 # } else { 995 # # HTML files not in the htmlDirectory are assumed under live under the 996 # # templateDirectory in the same directory as the problem. 997 # # Create an alias file (link) in the directory html/tmp/html which 998 # # points to the original file and return the URL of this alias. 999 # # Create all of the subdirectories of html/tmp/html which are needed 1000 # # using sure file to path. 1001 # 1002 # # $fileName is obtained from environment for PGeval 1003 # # it gives the full path to the current problem 1004 # my $filePath = directoryFromPath($fileName); 1005 # my $htmlFileSource = convertPath("$templateDirectory${filePath}$aux_file_path.html"); 1006 # my $link = "html/$studentLogin-$psvnNumber-set$setNumber-prob$probNum-$aux_file_path.$ext"; 1007 # my $linkPath = surePathToTmpFile($link); 1008 # $adr_output = "${tempURL}$link"; 1009 # if (-e $htmlFileSource) { 1010 # if (-e $linkPath) { 1011 # unlink($linkPath) || warn "Unable to unlink alias file at |$linkPath|"; 1012 # # destroy the old link. 1013 # } 1014 # symlink( $htmlFileSource, $linkPath) 1015 # || warn "The macro alias cannot create a link from |$linkPath| to |$htmlFileSource| <BR>" ; 1016 # } else { 1017 # warn("The macro alias cannot find an HTML file at: |$htmlFileSource|"); 1018 # } 1019 # } 1020 # } elsif ($ext eq 'gif') { 1021 # if ( $displayMode eq 'HTML' || 1022 # $displayMode eq 'HTML_tth'|| 1023 # $displayMode eq 'HTML_dpng'|| 1024 # $displayMode eq 'HTML_asciimath'|| 1025 # $displayMode eq 'HTML_LaTeXMathML'|| 1026 # $displayMode eq 'HTML_jsMath'|| 1027 # $displayMode eq 'HTML_img'|| 1028 # $displayMode eq 'Latex2HTML') { 1029 # ################################################################################ 1030 # # .gif FILES in HTML, HTML_tth, HTML_dpng, HTML_img, and Latex2HTML modes 1031 # ################################################################################ 1032 # 1033 # #warn "tempDirectory is $tempDirectory"; 1034 # #warn "file Path for auxiliary file is $aux_file_path"; 1035 # 1036 # # No changes are made for auxiliary files in the htmlDirectory or in the tempDirectory subtree. 1037 # if ( $aux_file_path =~ m|^$tempDirectory| ) { 1038 # $adr_output = $aux_file_path; 1039 # $adr_output =~ s|$tempDirectory|$tempURL|; 1040 # $adr_output .= ".$ext"; 1041 # #warn "adress out is $adr_output"; 1042 # } elsif ($aux_file_path =~ m|^$htmlDirectory| ) { 1043 # $adr_output = $aux_file_path; 1044 # $adr_output =~ s|$htmlDirectory|$htmlURL|; 1045 # $adr_output .= ".$ext"; 1046 # } else { 1047 # # files not in the htmlDirectory sub tree are assumed to live under the templateDirectory 1048 # # subtree in the same directory as the problem. 1049 # 1050 # # For a gif file the alias macro creates an alias under the html/images directory 1051 # # which points to the gif file in the problem directory. 1052 # # All of the subdirectories of html/tmp/gif which are needed are also created. 1053 # my $filePath = directoryFromPath($fileName); 1054 # 1055 # # $fileName is obtained from environment for PGeval 1056 # # it gives the full path to the current problem 1057 # my $gifSourceFile = convertPath("$templateDirectory${filePath}$aux_file_path.gif"); 1058 # #my $link = "gif/$studentLogin-$psvnNumber-set$setNumber-prob$probNum-$aux_file_path.$ext"; 1059 # 1060 # # Make file names work in Library Browser when the images in several 1061 # # files have the same names. 1062 # my $libFix = ""; 1063 # if ($setNumber eq "Undefined_Set") { 1064 # $libFix = $fileName; 1065 # $libFix =~ s!.*/!!; $libFix =~ s!\.pg(\..*)?$!!; 1066 # $libFix =~ s![^a-zA-Z0-9._-]!!g; 1067 # $libFix .= '-'; 1068 # } 1069 # 1070 # my $link = "gif/$setNumber-prob$probNum-$libFix$aux_file_path.$ext"; 1071 # 1072 # my $linkPath = surePathToTmpFile($link); 1073 # $adr_output = "${tempURL}$link"; 1074 # #warn "linkPath is $linkPath"; 1075 # #warn "adr_output is $adr_output"; 1076 # if (-e $gifSourceFile) { 1077 # if (-e $linkPath) { 1078 # unlink($linkPath) || warn "Unable to unlink old alias file at $linkPath"; 1079 # } 1080 # symlink($gifSourceFile, $linkPath) 1081 # || warn "The macro alias cannot create a link from |$linkPath| to |$gifSourceFile| <BR>" ; 1082 # } else { 1083 # warn("The macro alias cannot find a GIF file at: |$gifSourceFile|"); 1084 # } 1085 # } 1086 # } elsif ($displayMode eq 'TeX') { 1087 # ################################################################################ 1088 # # .gif FILES in TeX mode 1089 # ################################################################################ 1090 # 1091 # $setNumber =~ s/\./_/g; ## extra dots confuse latex's graphics package 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. 1095 # 1096 # my $gifFilePath; 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 # $gifFilePath = "$aux_file_path.gif"; 1101 # } else { 1102 # # we assume the file is in the same directory as the problem source file 1103 # $gifFilePath = $templateDirectory . directoryFromPath($fileName) . "$aux_file_path.gif"; 1104 # } 1105 # 1106 # my $gifFileName = fileFromPath($gifFilePath); 1107 # 1108 # $gifFileName =~ /^(.*)\.gif$/; 1109 # # my $pngFilePath = surePathToTmpFile("${tempDirectory}png/$probNum-$1.png"); 1110 # my $pngFilePath = surePathToTmpFile("${tempDirectory}png/$setNumber-$probNum-$1.png"); 1111 # my $returnCode = system "cat $gifFilePath | $envir{externalGif2PngPath} > $pngFilePath"; 1112 # 1113 # if ($returnCode or not -e $pngFilePath) { 1114 # die "failed to convert $gifFilePath to $pngFilePath using gif->png with $envir{externalGif2PngPath}: $!\n"; 1115 # } 1116 # 1117 # $adr_output = $pngFilePath; 1118 # } else { 1119 # # Since we're not creating PDF files, we're probably just using a plain 1120 # # vanilla latex. Hence, we need EPS images. 1121 # 1122 # ################################################################################ 1123 # # This is statement used below is system dependent. 1124 # # Notice that the range of colors is restricted when converting to postscript to keep the files small 1125 # # "cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmtops -noturn > $adr_output" 1126 # # "cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn > $adr_output" 1127 # ################################################################################ 1128 # if ($aux_file_path =~ m|^$htmlDirectory| or $aux_file_path =~ m|^$tempDirectory|) { 1129 # # To serve an eps file copy an eps version of the gif file to the subdirectory of eps/ 1130 # my $linkPath = directoryFromPath($fileName); 1131 # 1132 # my $gifSourceFile = "$aux_file_path.gif"; 1133 # my $gifFileName = fileFromPath($gifSourceFile); 1134 # $adr_output = surePathToTmpFile("$tempDirectory/eps/$studentLogin-$psvnNumber-$gifFileName.eps") ; 1135 # 1136 # if (-e $gifSourceFile) { 1137 # #system("cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output") 1138 # system("cat $gifSourceFile | ${externalGif2EpsPath} > $adr_output" ) 1139 # && die "Unable to create eps file:\n |$adr_output| from file\n |$gifSourceFile|\n in problem $probNum " . 1140 # "using the system dependent script\n |${externalGif2EpsPath}| \n"; 1141 # } else { 1142 # die "|$gifSourceFile| cannot be found. Problem number: |$probNum|"; 1143 # } 1144 # } else { 1145 # # To serve an eps file copy an eps version of the gif file to a subdirectory of eps/ 1146 # my $filePath = directoryFromPath($fileName); 1147 # my $gifSourceFile = "${templateDirectory}${filePath}$aux_file_path.gif"; 1148 # #print "content-type: text/plain \n\nfileName = $fileName and aux_file_path =$aux_file_path<BR>"; 1149 # $adr_output = surePathToTmpFile("eps/$studentLogin-$psvnNumber-set$setNumber-prob$probNum-$aux_file_path.eps"); 1150 # 1151 # if (-e $gifSourceFile) { 1152 # #system("cat $gifSourceFile | /usr/math/bin/giftopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output") && 1153 # #warn "Unable to create eps file: |$adr_output|\n from file\n |$gifSourceFile|\n in problem $probNum"; 1154 # #warn "Help ${:externalGif2EpsPath}" unless -x "${main::externalGif2EpsPath}"; 1155 # system("cat $gifSourceFile | ${externalGif2EpsPath} > $adr_output" ) 1156 # && die "Unable to create eps file:\n |$adr_output| from file\n |$gifSourceFile|\n in problem $probNum " . 1157 # "using the system dependent commands \n |${externalGif2EpsPath}| \n "; 1158 # } else { 1159 # die "|$gifSourceFile| cannot be found. Problem number: |$probNum|"; 1160 # } 1161 # } 1162 # } 1163 # } else { 1164 # die "Error in alias: dangerousMacros.pl: unrecognizable displayMode = $displayMode"; 1165 # } 1166 # } elsif ($ext eq 'png') { 1167 # if ( $displayMode eq 'HTML' || 1168 # $displayMode eq 'HTML_tth'|| 1169 # $displayMode eq 'HTML_dpng'|| 1170 # $displayMode eq 'HTML_asciimath'|| 1171 # $displayMode eq 'HTML_LaTeXMathML'|| 1172 # $displayMode eq 'HTML_jsMath'|| 1173 # $displayMode eq 'HTML_img'|| 1174 # $displayMode eq 'Latex2HTML') { 1175 # ################################################################################ 1176 # # .png FILES in HTML, HTML_tth, HTML_dpng, HTML_img, etc. and Latex2HTML modes 1177 # ################################################################################ 1178 # 1179 # #warn "tempDirectory is $tempDirectory"; 1180 # #warn "file Path for auxiliary file is $aux_file_path"; 1181 # 1182 # # No changes are made for auxiliary files in the htmlDirectory or in the tempDirectory subtree. 1183 # if ( $aux_file_path =~ m|^$tempDirectory| ) { 1184 # $adr_output = $aux_file_path; 1185 # $adr_output =~ s|$tempDirectory|$tempURL|; 1186 # $adr_output .= ".$ext"; 1187 # #warn "adress out is $adr_output"; 1188 # } elsif ($aux_file_path =~ m|^$htmlDirectory| ) { 1189 # $adr_output = $aux_file_path; 1190 # $adr_output =~ s|$htmlDirectory|$htmlURL|; 1191 # $adr_output .= ".$ext"; 1192 # } else { 1193 # # files not in the htmlDirectory sub tree are assumed to live under the templateDirectory 1194 # # subtree in the same directory as the problem. 1195 # 1196 # # For a png file the alias macro creates an alias under the html/images directory 1197 # # which points to the png file in the problem directory. 1198 # # All of the subdirectories of html/tmp/gif which are needed are also created. 1199 # my $filePath = directoryFromPath($fileName); 1200 # 1201 # # $fileName is obtained from environment for PGeval 1202 # # it gives the full path to the current problem 1203 # my $pngSourceFile = convertPath("$templateDirectory${filePath}$aux_file_path.png"); 1204 # my $link = "gif/$studentLogin-$psvnNumber-set$setNumber-prob$probNum-$aux_file_path.$ext"; 1205 # my $linkPath = surePathToTmpFile($link); 1206 # $adr_output = "${tempURL}$link"; 1207 # #warn "linkPath is $linkPath"; 1208 # #warn "adr_output is $adr_output"; 1209 # if (-e $pngSourceFile) { 1210 # if (-e $linkPath) { 1211 # unlink($linkPath) || warn "Unable to unlink old alias file at $linkPath"; 1212 # } 1213 # symlink($pngSourceFile, $linkPath) 1214 # || warn "The macro alias cannot create a link from |$linkPath| to |$pngSourceFile| <BR>" ; 1215 # } else { 1216 # warn("The macro alias cannot find a PNG file at: |$pngSourceFile|"); 1217 # } 1218 # } 1219 # } elsif ($displayMode eq 'TeX') { 1220 # ################################################################################ 1221 # # .png FILES in TeX mode 1222 # ################################################################################ 1223 # 1224 # $setNumber =~ s/\./_/g; ## extra dots confuse latex's graphics package 1225 # if ($envir{texDisposition} eq "pdf") { 1226 # # We're going to create PDF files with our TeX (using pdflatex), so we 1227 # # need images in PNG format. what luck! they're already in PDF format! 1228 # 1229 # my $pngFilePath; 1230 # 1231 # if ($aux_file_path =~ m/^$htmlDirectory/ or $aux_file_path =~ m/^$tempDirectory/) { 1232 # # we've got a full pathname to a file 1233 # $pngFilePath = "$aux_file_path.png"; 1234 # } else { 1235 # # we assume the file is in the same directory as the problem source file 1236 # $pngFilePath = $templateDirectory . directoryFromPath($fileName) . "$aux_file_path.png"; 1237 # } 1238 # 1239 # $adr_output = $pngFilePath; 1240 # } else { 1241 # # Since we're not creating PDF files, we're probably just using a plain 1242 # # vanilla latex. Hence, we need EPS images. 1243 # 1244 # ################################################################################ 1245 # # This is statement used below is system dependent. 1246 # # Notice that the range of colors is restricted when converting to postscript to keep the files small 1247 # # "cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmtops -noturn > $adr_output" 1248 # # "cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn > $adr_output" 1249 # ################################################################################ 1250 # 1251 # if ($aux_file_path =~ m|^$htmlDirectory| or $aux_file_path =~ m|^$tempDirectory|) { 1252 # # To serve an eps file copy an eps version of the png file to the subdirectory of eps/ 1253 # my $linkPath = directoryFromPath($fileName); 1254 # 1255 # my $pngSourceFile = "$aux_file_path.png"; 1256 # my $pngFileName = fileFromPath($pngSourceFile); 1257 # $adr_output = surePathToTmpFile("$tempDirectory/eps/$studentLogin-$psvnNumber-$pngFileName.eps") ; 1258 # 1259 # if (-e $pngSourceFile) { 1260 # #system("cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output") 1261 # system("cat $pngSourceFile | ${externalPng2EpsPath} > $adr_output" ) 1262 # && die "Unable to create eps file:\n |$adr_output| from file\n |$pngSourceFile|\n in problem $probNum " . 1263 # "using the system dependent commands\n |${externalPng2EpsPath}| \n"; 1264 # } else { 1265 # die "|$pngSourceFile| cannot be found. Problem number: |$probNum|"; 1266 # } 1267 # } else { 1268 # # To serve an eps file copy an eps version of the png file to a subdirectory of eps/ 1269 # my $filePath = directoryFromPath($fileName); 1270 # my $pngSourceFile = "${templateDirectory}${filePath}$aux_file_path.png"; 1271 # #print "content-type: text/plain \n\nfileName = $fileName and aux_file_path =$aux_file_path<BR>"; 1272 # $adr_output = surePathToTmpFile("eps/$studentLogin-$psvnNumber-set$setNumber-prob$probNum-$aux_file_path.eps") ; 1273 # if (-e $pngSourceFile) { 1274 # #system("cat $pngSourceFile | /usr/math/bin/pngtopnm | /usr/math/bin/pnmdepth 1 | /usr/math/bin/pnmtops -noturn>$adr_output") && 1275 # #warn "Unable to create eps file: |$adr_output|\n from file\n |$pngSourceFile|\n in problem $probNum"; 1276 # #warn "Help ${externalPng2EpsPath}" unless -x "${externalPng2EpsPath}"; 1277 # system("cat $pngSourceFile | ${externalPng2EpsPath} > $adr_output" ) 1278 # && die "Unable to create eps file:\n |$adr_output| from file\n |$pngSourceFile|\n in problem $probNum " . 1279 # "using the system dependent commands\n |${externalPng2EpsPath}| \n "; 1280 # } else { 1281 # die "|$pngSourceFile| cannot be found. Problem number: |$probNum|"; 1282 # } 1283 # } 1284 # } 1285 # } else { 1286 # warn "Error in alias: dangerousMacros.pl","unrecognizable displayMode = $displayMode",""; 1287 # } 1288 # } else { # $ext is not recognized 1289 # ################################################################################ 1290 # # FILES with unrecognized file extensions in any display modes 1291 # ################################################################################ 1292 # 1293 # warn "Error in the macro alias. Alias does not understand how to process files with extension $ext. (Path ot problem file is $fileName) "; 1294 # } 1295 # 1296 # warn "The macro alias was unable to form a URL for some auxiliary file used in this problem." unless $adr_output; 1297 # return $adr_output; 1298 # } 1299 # 1300 # =head2 sourceAlias 1301 # 1302 # sourceAlias($path_to_PG_file); 1303 # 1304 # Returns a relative URL to the F<source.pl> script, which may be installed in a 1305 # course's F<html> directory to allow formatted viewing of the problem source. 1306 # 1307 # =cut 1308 # 1309 # # ^function sourceAlias 1310 # # ^uses PG_restricted_eval 1311 # # ^uses %envir 1312 # # ^uses $envir{inputs_ref} 1313 # # ^uses $envir{psvn} 1314 # # ^uses $envir{probNum} 1315 # # ^uses $envir{displayMode} 1316 # # ^uses $envir{courseName} 1317 # # ^uses $envir{sessionKey} 1318 # sub sourceAlias { 1319 # my $path_to_file = shift; 1320 # my $envir = PG_restricted_eval(q!\%main::envir!); 1321 # my $user = $envir->{inputs_ref}->{user}; 1322 # $user = " " unless defined($user); 1323 # my $out = 'source.pl?probSetKey=' . $envir->{psvn}. 1324 # '&probNum=' . $envir->{probNum} . 1325 # '&Mode=' . $envir->{displayMode} . 1326 # '&course=' . $envir->{courseName} . 1327 # '&user=' . $user . 1328 # '&displayPath=' . $path_to_file . 1329 # '&key=' . $envir->{sessionKey}; 1330 # 1331 # $out; 1332 # } 1333 1334 # 1335 # # 1336 # # Some constants that can be used in perl experssions 1337 # # 1338 # 1339 # # ^function i 1340 # # ^uses $_parser_loaded 1341 # # ^uses &Complex::i 1342 # # ^uses &Value::Package 1343 # sub i () { 1344 # # check if Parser.pl is loaded, otherwise use Complex package 1345 # if (!eval(q!$main::_parser_loaded!)) {return Complex::i} 1346 # return Value->Package("Formula")->new('i')->eval; 1347 # } 1348 # 1349 # # ^function j 1350 # # ^uses $_parser_loaded 1351 # # ^uses &Value::Package 1352 # sub j () { 1353 # if (!eval(q!$main::_parser_loaded!)) {return 'j'} 1354 # Value->Package("Formula")->new('j')->eval; 1355 # } 1356 # 1357 # # ^function k 1358 # # ^uses $_parser_loaded 1359 # # ^uses &Value::Package 1360 # sub k () { 1361 # if (!eval(q!$main::_parser_loaded!)) {return 'k'} 1362 # Value->Package("Formula")->new('k')->eval; 1363 # } 1364 # 1365 # # ^function pi 1366 # # ^uses &Value::Package 1367 # sub pi () {Value->Package("Formula")->new('pi')->eval} 1368 # 1369 # # ^function Infinity 1370 # # ^uses &Value::Package 1371 # sub Infinity () {Value->Package("Infinity")->new()} 1372 # 1373 # 1374 # # ^function abs 1375 # # ^function sqrt 1376 # # ^function exp 1377 # # ^function log 1378 # # ^function sin 1379 # # ^function cos 1380 # # ^function atan2 1381 # # 1382 # # Allow these functions to be overridden 1383 # # (needed for log() to implement $useBaseTenLog) 1384 # # 1385 # use subs 'abs', 'sqrt', 'exp', 'log', 'sin', 'cos', 'atan2'; 1386 # sub abs($) {return CORE::abs($_[0])}; 1387 # sub sqrt($) {return CORE::sqrt($_[0])}; 1388 # sub exp($) {return CORE::exp($_[0])}; 1389 # sub log($) {return CORE::log($_[0])}; 1390 # sub sin($) {return CORE::sin($_[0])}; 1391 # sub cos($) {return CORE::cos($_[0])}; 1392 # sub atan2($$) {return CORE::atan2($_[0],$_[1])}; 1393 # 1394 # sub Parser::defineLog {eval {sub log($) {CommonFunction->Call("log",@_)}}}; 1395 sub foobar { 1396 my $self = shift; 1397 1398 } 1399 1;
aubreyja at gmail dot com | ViewVC Help |
Powered by ViewVC 1.0.9 |