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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 61 - (download) (as text) (annotate)
Fri Jun 22 21:29:58 2001 UTC (18 years, 8 months ago) by gage
File size: 39691 byte(s)
Fixed errors in sourceAlias

Modified parts of alias so that PG_restricted_eval was not used.
(This is unnecessary as long as we use forking to create a child
with the same namespace.)

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9