#!/usr/local/bin/perl ################################################################################ # WeBWorK # # Copyright (c) 1995-2002 University of Rochester # All rights reserved # ################################################################################ use lib '.'; use webworkInit; # WeBWorKInitLine use strict; =head1 NAME ImageGenerator.pm =head1 SYNPOSIS Create an object for holding bits of math for LaTeX, and then to process them later. my $imgen = new ImageGenerator; #create a image generator $imgen->initialize(\%envir); # provide basic data in preparation of image collection $imgen->add(string); # add a new LaTeX string to be processed. # Should be in math mode with \( or \[ # It returns the html tag $imgen->getCount(); # Returns the number of images which have been added $imgen->tmpurl(); # Returns the beginning of the html path $imgen->render(); # Generates the images. By default, we reuse old # images when reasonable, unless passed a flag # refresh=>'yes' (or 1) =head1 DESCRIPTION This module defines an object which holds bits of LaTeX math for generating images. =cut package ImageGenerator; =head2 new Creates the ImageGenerator object. =cut sub new { my $class = shift; my $self = { latexlines => [], count => 0, tmppath => "", tmpURLstart=>"", filenamestart=> "" }; bless $self, $class; } sub initialize { my $self = shift; my $envir = shift; # pointer to problem envirment hash my $problemnum = $envir->{'probNum'}; my $studname = $envir->{'studentLogin'}; my $psvn = $envir->{'psvn'}; my $setname = $envir->{'setNumber'}; my $tmpURLstart = $envir->{'tempURL'}; my $path=main::surePathToTmpFile(main::convertPath("png/$setname/$psvn/foo")); $path =~ s/foo$//; # remove final foo $self->{sourceFile} = $envir->{templateDirectory} . "/" . $envir->{fileName}; $self->{tmpURLstart} = $tmpURLstart."png/$setname/$psvn"; $self->{tmppath}=$path; $self->{filenamestart}="$studname-prob${problemnum}image"; } # Add another string to list to be LaTeX'ed # return the tag sub add { my $self = shift; my $newstr = shift; my $tag = $newstr; $self->{count}++; my $tempURL= $self->tmpurl()."$self->{count}.png"; if ($tag =~ /^\\\(/) { $tag =~ s|^\\\( *||; $tag =~ s|\\\)$||; $tag = qq!$tag!; } else { # Displayed math comes in with \[ stuff \]. To get a good # bounding box through preview, we change that to \( \displaystyle{ # stuff } \), and then center the resulting image $tag =~ s|^\\\[ *||; $tag =~ s|\\\]$||; $newstr = '\(\displaystyle{'.$tag.'}\)'; $tag = qq!
$tag
!; } push @{$self->{latexlines}}, $newstr; return $tag; } sub getCount { my $self = shift; return($self->{count}); } sub tmpurl { my $self = shift; return("$self->{tmpURLstart}/$self->{filenamestart}"); } sub render { my $self = shift; my %opts = @_; if($self->{count}==0) {return ;} # Don't run latex if there are no images my $refreshMe = 0; if (defined($opts{refresh}) and (($opts{refresh} eq "yes") or ($opts{refresh} == 1))) { $refreshMe = 1; } # $refreshMe = 1; # Uncomment for testing my $latexfilenamebase = $self->{tmppath}.$self->{filenamestart}; my $sourcePath = $self->{sourceFile}; my $tempFile = "${latexfilenamebase}".$self->{count}.".png"; # last image if ($refreshMe or not -e $tempFile or (stat $sourcePath)[9] > (stat $tempFile)[9]) { # image file doesn't exist, or source file is newer then image file # or we just want new images produced # my $old_cdir = `pwd`; # cd for running latex # chomp($old_cdir); chdir($self->{tmppath}) || warn "Could not move into temporary directory $self->{tmppath}"; if (-e "$latexfilenamebase.tex") { unlink("$latexfilenamebase.tex") || warn "Could not delete old LaTeX file"; } local *LATEXME; open(LATEXME,">$latexfilenamebase.tex") || warn "Cannot create temporary tex file"; print LATEXME <<'EOT'; \documentclass[12pt]{article} \nonstopmode \usepackage{amsmath,amsfonts,amssymb} \def\gt{>} \def\lt{<} \usepackage[active,textmath,displaymath]{preview} \begin{document} EOT my $j; for $j (@{$self->{latexlines}}) { print LATEXME "\n$j\n"; } print LATEXME '\end{document}'."\n"; close(LATEXME); chmod(0666, "$latexfilenamebase.tex") || warn "Could not change permissions on $latexfilenamebase.tex"; my $error_log = '/dev/null'; ## by default do not log error messages $error_log = &Global::getErrorLog if $Global::imageDebugMode; $ENV{PATH} .= "$Global::extendedPath"; my $dvipng_res = int($Global::dvipngScaling * 1000+0.5); my $cmdout=""; # remove any old files using this name unlink("$self->{filenamestart}.dvi","$self->{filenamestart}.log", "$self->{filenamestart}.aux","missfont.log"); $cmdout=system("$Global::externalLatexPath $self->{filenamestart}.tex >>$error_log 2>>$error_log"); warn "$Global::externalLatexPath $self->{filenamestart}.tex >>$error_log 2>>$error_log -- FAILED in ImageGenerator returned $cmdout" if $cmdout; $cmdout=system("$Global::externalDvipngPath -x$dvipng_res -bgTransparent -Q$Global::dvipngShrinkFactor -mode $Global::dvipngMode -D$Global::dvipngDPI $self->{filenamestart}.dvi >>$error_log 2>>$error_log"); warn "$Global::externalDvipngPath -x$dvipng_res -bgTransparent -Q$Global::dvipngShrinkFactor -mode $Global::dvipngMode -D$Global::dvipngDPI $self->{filenamestart}.dvi >>$error_log 2>>$error_log -- FAILED in ImageGenerator.pm returned $cmdout" if $cmdout !=256; unless ($Global::imageDebugMode) { unlink("$self->{filenamestart}.dvi","$self->{filenamestart}.log", "$self->{filenamestart}.tex", "$self->{filenamestart}.aux" ); } # chdir($old_cdir); } } 1;