[system] / trunk / pg / macros / dangerousMacros.pl Repository:
ViewVC logotype

View of /trunk/pg/macros/dangerousMacros.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1250 - (download) (as text) (annotate)
Mon Jun 23 15:43:11 2003 UTC (16 years, 5 months ago) by gage
File size: 48009 byte(s)
Made changes required to allow caching of these files.
My tests indicate that these changes are compatible with webwork1.8
One possible problem might be the mail-to answer macros
which access the environement variable directly
I think I have this properly patched, but it has not been
tested yet.
--Mike

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9