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