[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 407 - (download) (as text) (annotate)
Mon Jun 24 18:32:49 2002 UTC (10 years, 10 months ago) by gage
File size: 40010 byte(s)
Commented out the debugging messages again.

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9