[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 1091 - (download) (as text) (annotate)
Mon Jun 9 21:53:11 2003 UTC (16 years, 7 months ago) by gage
File size: 47340 byte(s)
Added > /dev/null tags to the commands which run tex and dvi for
HTML_img mode.  These will probably work now for the most part.
I don't know how well this will work if there is an error in
getting either tex or dvips to run.

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9