[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 10 - (download) (as text) (annotate)
Fri Jun 15 21:06:18 2001 UTC (11 years, 11 months ago) by sam
File size: 37238 byte(s)
nothing should change

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9