[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 2151 - (download) (as text) (annotate)
Sat May 22 01:23:17 2004 UTC (15 years, 6 months ago) by gage
File size: 48200 byte(s)
Roll back the previous changes.  They were added to HEAD instead of to the experimental branch.

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9