Parent Directory
|
Revision Log
yo shout! answer previewing is working. -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 $texFile = "$wd/equation.tex"; 235 my $dviFile = "$wd/equation.dvi"; 236 my $dviFile2 = "$wd/equationequation.dvi"; 237 my $dviCall = "equation"; 238 my $pngFile = "$wd/equation1.png"; 239 240 die "dvipng working directory $wd doesn't exist -- caller should have created it for us!\n" 241 unless -e $wd; 242 243 # write the tex file 244 local *TEX; 245 open TEX, ">", $texFile; 246 print TEX <<'EOF'; 247 % BEGIN HEADER 248 \batchmode 249 \documentclass[12pt]{article} 250 \usepackage{amsmath,amsfonts,amssymb} 251 \def\gt{>} 252 \def\lt{<} 253 \usepackage[active,textmath,displaymath]{preview} 254 \begin{document} 255 % END HEADER 256 EOF 257 print TEX "\\( \\displaystyle{$tex} \\)\n"; 258 print TEX <<'EOF'; 259 % BEGIN FOOTER 260 \end{document} 261 % END FOOTER 262 EOF 263 close TEX; 264 265 # call latex 266 system "cd $wd && $latex $texFile"; 267 268 return 0 unless -e $dviFile; 269 270 # change the name of the DVI file to get around dvipng's crackheadedness 271 system "/bin/mv", $dviFile, $dviFile2; 272 273 # call dvipng 274 system "cd $wd && $dvipng $dviCall" and die "dvipng:dvipng failed: $!"; 275 276 return 0 unless -e $pngFile; 277 278 system "/bin/mv", $pngFile, $targetPath and die "Failed to mv: $!\n"; 279 } 280 281 1;
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |