Parent Directory
|
Revision Log
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 |