[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 2232 - (download) (as text) (annotate)
Mon May 31 15:44:43 2004 UTC (15 years, 6 months ago) by jj
File size: 48447 byte(s)
Re-use on-the-fly graphs, unless problem seed has change, source file has changed, or the problem is being rendered without being part of a real set.

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9