[system] / trunk / webwork / system / courseScripts / dangerousMacros.pl Repository:
ViewVC logotype

Annotation of /trunk/webwork/system/courseScripts/dangerousMacros.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (view) (download) (as text)

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9