[system] / trunk / webwork2 / lib / WeBWorK / PG / IO.pm Repository:
ViewVC logotype

View of /trunk/webwork2/lib/WeBWorK/PG/IO.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 662 - (download) (as text) (annotate)
Mon Nov 25 23:53:30 2002 UTC (10 years, 5 months ago) by sh002i
File size: 7966 byte(s)
fixed dvipng (again!)
-sam

    1 ################################################################################
    2 # WeBWorK mod-perl (c) 2000-2002 WeBWorK Project
    3 # $Id$
    4 ################################################################################
    5 
    6 package WeBWorK::PG::IO;
    7 
    8 use strict;
    9 use warnings;
   10 use Exporter;
   11 use GD;
   12 
   13 our @ISA = qw(Exporter);
   14 our @EXPORT = (
   15   #'REMOTE_HOST',             # replaced with a problem envir. variable
   16   #'REMOTE_ADDR',             # replaced with a problem envir. variable
   17   'includePGtext',
   18   #'send_mail_to',            # moved to IO.pl
   19   'read_whole_problem_file',
   20   'read_whole_file',
   21   'convertPath',
   22   'getDirDelim',
   23   #'getCourseTempDirectory',  # moved to IO.pl
   24   #'surePathToTmpFile',       # moved to IO.pl
   25   'fileFromPath',
   26   'directoryFromPath',
   27   'createFile',
   28   'createDirectory',
   29   'getImageDimmensions',
   30   'dvipng',
   31 );
   32 
   33 # The above symbols are exported into the caller's namespace. This is usually
   34 # done so that they can be shared with a problem's safe compartment via
   35 # WeBWorK::PG::Translator. To do this, add the symbol's name to the
   36 # %shared_subroutine_hash hash in lib/WeBWorK/PG/Translator.pm.
   37 
   38 =head1 Private functions (not methods) used by PGtranslator for file IO.
   39 
   40 =head2 includePGtext
   41 
   42   includePGtext($string_ref, $envir_ref)
   43 
   44 Calls C<createPGtext> recursively with the $safeCompartment variable set to 0
   45 so that the rendering continues in the current safe compartment.  The output
   46 is the same as the output from createPGtext. This is used in processing
   47 some of the sample CAPA files.
   48 
   49 =cut
   50 
   51 sub includePGtext  {
   52   my $evalString = shift;
   53   if (ref($evalString) eq 'SCALAR') {
   54     $evalString = $$evalString;
   55   }
   56   $evalString =~ s/\nBEGIN_TEXT/TEXT\(EV3\(<<'END_TEXT'\)\);/g;
   57   $evalString =~ s/\\/\\\\/g; # \ can't be used for escapes because of TeX conflict
   58   $evalString =~ s/~~/\\/g;   # use ~~ as escape instead, use # for comments
   59   no strict;
   60   eval("package main; $evalString") ;
   61   my $errors = $@;
   62   die eval(q! "ERROR in included file:\n$main::envir{probFileName}\n $errors\n"!) if $errors;
   63   use strict;
   64   return "";
   65 }
   66 
   67 =head2   read_whole_problem_file
   68 
   69   read_whole_problem_file($filePath);
   70 
   71   Returns: A reference to a string containing
   72            the contents of the file.
   73 
   74 Don't use for huge files. The file name will have .pg appended to it if it doesn't
   75 already end in .pg.  Files may become double spaced.?  Check the join below. This is
   76 used in importing additional .pg files as is done in the
   77 sample problems translated from CAPA.
   78 
   79 =cut
   80 
   81 sub read_whole_problem_file {
   82   my $filePath = shift;
   83   $filePath =~s/^\s*//; # get rid of initial spaces
   84   $filePath =~s/\s*$//; # get rid of final spaces
   85   $filePath = "$filePath.pg" unless $filePath =~ /\.pg$/;
   86   read_whole_file($filePath);
   87 }
   88 
   89 sub read_whole_file {
   90   my $filePath = shift;
   91   local (*INPUT);
   92   open(INPUT, "<$filePath") || die "$0: readWholeProblemFile subroutine: <BR>Can't read file $filePath";
   93   local($/)=undef;
   94   my $string = <INPUT>;  # can't append spaces because this causes trouble with <<'EOF'   \nEOF construction
   95   close(INPUT);
   96   \$string;
   97 }
   98 
   99 =head2 convertPath
  100 
  101   $path = convertPath($path);
  102 
  103 Normalizes the delimiters in the path using delimiter from C<&getDirDelim()>
  104 which is defined in C<Global.pm>.
  105 
  106 =cut
  107 
  108 sub convertPath {
  109     return wantarray ? @_ : shift;
  110 }
  111 
  112 # hacks to make this program work independent of Global.pm
  113 sub getDirDelim {
  114   return ("/");
  115 }
  116 
  117 =head2 fileFromPath
  118 
  119   $fileName = fileFromPath($path)
  120 
  121 Defined in C<FILE.pl>.
  122 
  123 Uses C<&getDirDelim()> to determine the path delimiter.  Returns the last segment
  124 of the path (after the last delimiter.)
  125 
  126 =cut
  127 
  128 sub fileFromPath {
  129   my $path = shift;
  130   my $delim =&getDirDelim();
  131   $path =  convertPath($path);
  132   $path =~  m|([^$delim]+)$|;
  133   $1;
  134 }
  135 
  136 =head2 directoryFromPath
  137 
  138 
  139   $directoryPath = directoryFromPath($path)
  140 
  141 Defined in C<FILE.pl>.
  142 
  143 Uses C<&getDirDelim()> to determine the path delimiter.  Returns the initial segments
  144 of the of the path (up to the last delimiter.)
  145 
  146 =cut
  147 
  148 sub directoryFromPath {
  149   my $path = shift;
  150   my $delim =&getDirDelim();
  151   $path = convertPath($path);
  152   $path =~ s|[^$delim]*$||;
  153   $path;
  154 }
  155 
  156 =head2 createFile
  157 
  158   createFile($filePath);
  159 
  160 Calls C<FILE.pl> version of createFile with
  161 C<createFile($filePath,0660(permission),$Global::numericalGroupID)>
  162 
  163 =cut
  164 
  165 sub createFile {
  166   my ($fileName, $permission, $numgid) = @_;
  167   open(TEMPCREATEFILE, ">$fileName")
  168     or die "Can't open $fileName: $!";
  169   my @stat = stat TEMPCREATEFILE;
  170   close(TEMPCREATEFILE);
  171 
  172   ## if the owner of the file is running this script (e.g. when the file is first created)
  173   ## set the permissions and group correctly
  174   if ($< == $stat[4]) {
  175     my $tmp = chmod($permission,$fileName)
  176       or warn "Can't do chmod($permission, $fileName): $!";
  177     chown(-1,$numgid,$fileName)
  178       or warn "Can't do chown($numgid, $fileName): $!";
  179   }
  180 }
  181 
  182 sub createDirectory {
  183   my ($dirName, $permission, $numgid) = @_;
  184   mkdir($dirName, $permission)
  185     or warn "Can't do mkdir($dirName, $permission): $!";
  186   chmod($permission, $dirName)
  187     or warn "Can't do chmod($permission, $dirName): $!";
  188   unless ($numgid == -1) {
  189     chown(-1,$numgid,$dirName)
  190       or warn "Can't do chown(-1,$numgid,$dirName): $!";
  191   }
  192 }
  193 
  194 =head2 getImageDimmensions
  195 
  196 (height, width) = getImageDimmensions(imagePath)
  197 
  198 Returns the height and width of an image, given a path the the image file. Uses GD
  199 
  200 =cut
  201 
  202 sub getImageDimmensions($) {
  203   my $imageName = shift;
  204   my $image = GD::Image->new($imageName);
  205   my ($width, $height) = $image->getBounds();
  206   return ($height, $width);
  207 }
  208 
  209 =head2 dvipng
  210 
  211 dvipng(wd, latex, dvpng, tex, targetPath)
  212 
  213   $wd,        # working directory, for latex and dvipng garbage
  214         # (must already exist!)
  215   $latex,     # path to latex binary
  216   $dvipng,    # path to dvipng binary
  217   $tex,       # tex string representing equation
  218   $targetPath # location of resulting image file
  219 
  220 Uses LaTeX and dvipng to convert a LaTeX math expression into a PNG image.
  221 
  222 =cut
  223 
  224 sub dvipng($$$$$) {
  225   my (
  226     $wd,        # working directory, for latex and dvipng garbage
  227                 # (must already exist!)
  228     $latex,     # path to latex binary
  229     $dvipng,    # path to dvipng binary
  230     $tex,       # tex string representing equation
  231     $targetPath # location of resulting image file
  232   ) = @_;
  233 
  234   my $dvipngBroken = 0;
  235 
  236   my $texFile  = "$wd/equation.tex";
  237   my $dviFile  = "$wd/equation.dvi";
  238   my $dviFile2 = "$wd/equationequation.dvi";
  239   my $dviCall  = "equation";
  240   my $pngFile  = "$wd/equation1.png";
  241 
  242   unless (-e $wd) {
  243     die "dvipng working directory $wd doesn't exist -- caller should have created it for us!\n";
  244     return 0;
  245   }
  246 
  247   # write the tex file
  248   local *TEX;
  249   open TEX, ">", $texFile or warn "Failed to create $texFile: $!";
  250   print TEX <<'EOF';
  251 % BEGIN HEADER
  252 \batchmode
  253 \documentclass[12pt]{article}
  254 \usepackage{amsmath,amsfonts,amssymb}
  255 \def\gt{>}
  256 \def\lt{<}
  257 \usepackage[active,textmath,displaymath]{preview}
  258 \begin{document}
  259 % END HEADER
  260 EOF
  261   print TEX "\\( \\displaystyle{$tex} \\)\n";
  262   print TEX <<'EOF';
  263 % BEGIN FOOTER
  264 \end{document}
  265 % END FOOTER
  266 EOF
  267   close TEX;
  268 
  269   # call latex
  270   system "cd $wd && $latex $texFile"
  271     and warn "Failed to call $latex with $texFile: $!";
  272 
  273   unless (-e $dviFile) {
  274     warn "Failed to generate DVI file $dviFile";
  275     return 0;
  276   }
  277 
  278   if ($dvipngBroken) {
  279     # change the name of the DVI file to get around dvipng's
  280     # crackheadedness. This is no longer needed with the newest
  281     # version of dvipng (10 something)
  282     system "/bin/mv", $dviFile, $dviFile2;
  283   }
  284 
  285   # call dvipng -- using warn instead of die passes some extra information
  286   # back to the user the complete warning is still printed in the apache
  287   # error log and a simple message (math2img failed) is returned to the
  288   # webpage.
  289   my $cmdout;
  290   $cmdout = system "cd $wd && $dvipng $dviCall"
  291     and warn "Failed to call$dvipng with $dviCall: $! with signal $cmdout";
  292 
  293   unless (-e $pngFile) {
  294     warn "Failed to create PNG file $pngFile";
  295     return 0;
  296   }
  297 
  298   $cmdout = system "/bin/mv", $pngFile, $targetPath and warn "Failed to mv: /bin/mv  $pngFile $targetPath $!. Call returned $cmdout. \n";
  299 }
  300 
  301 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9