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