| 1 | ################################################################################ |
1 | ################################################################################ |
| 2 | # WeBWorK Online Homework Delivery System |
2 | # WeBWorK Online Homework Delivery System |
| 3 | # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ |
3 | # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ |
| 4 | # $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Problem.pm,v 1.171 2005/06/28 00:16:08 sh002i Exp $ |
4 | # $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/Problem.pm,v 1.172 2005/07/04 13:18:47 dpvc Exp $ |
| 5 | # |
5 | # |
| 6 | # This program is free software; you can redistribute it and/or modify it under |
6 | # This program is free software; you can redistribute it and/or modify it under |
| 7 | # the terms of either: (a) the GNU General Public License as published by the |
7 | # the terms of either: (a) the GNU General Public License as published by the |
| 8 | # Free Software Foundation; either version 2, or (at your option) any later |
8 | # Free Software Foundation; either version 2, or (at your option) any later |
| 9 | # version, or (b) the "Artistic License" which comes with this package. |
9 | # version, or (b) the "Artistic License" which comes with this package. |
| … | |
… | |
| 29 | use File::Path qw(rmtree); |
29 | use File::Path qw(rmtree); |
| 30 | use WeBWorK::Form; |
30 | use WeBWorK::Form; |
| 31 | use WeBWorK::PG; |
31 | use WeBWorK::PG; |
| 32 | use WeBWorK::PG::ImageGenerator; |
32 | use WeBWorK::PG::ImageGenerator; |
| 33 | use WeBWorK::PG::IO; |
33 | use WeBWorK::PG::IO; |
| 34 | use WeBWorK::Utils qw(writeLog writeCourseLog encodeAnswers decodeAnswers ref2string makeTempDirectory); |
34 | use WeBWorK::Utils qw(readFile writeLog writeCourseLog encodeAnswers decodeAnswers ref2string makeTempDirectory); |
| 35 | use WeBWorK::DB::Utils qw(global2user user2global findDefaults); |
35 | use WeBWorK::DB::Utils qw(global2user user2global findDefaults); |
| 36 | use WeBWorK::Timing; |
36 | use WeBWorK::Timing; |
| 37 | use URI::Escape; |
37 | use URI::Escape; |
| 38 | |
38 | |
| 39 | use WeBWorK::Utils::Tasks qw(fake_set fake_problem); |
39 | use WeBWorK::Utils::Tasks qw(fake_set fake_problem); |
| … | |
… | |
| 215 | $header .= $showAttemptResults ? CGI::th("Result") : ""; |
215 | $header .= $showAttemptResults ? CGI::th("Result") : ""; |
| 216 | $header .= $showMessages ? CGI::th("Messages") : ""; |
216 | $header .= $showMessages ? CGI::th("Messages") : ""; |
| 217 | my $fully = ''; |
217 | my $fully = ''; |
| 218 | my @tableRows = ( $header ); |
218 | my @tableRows = ( $header ); |
| 219 | my $numCorrect = 0; |
219 | my $numCorrect = 0; |
|
|
220 | my $tthPreambleCache; |
| 220 | foreach my $name (@answerNames) { |
221 | foreach my $name (@answerNames) { |
| 221 | my $answerResult = $pg->{answers}->{$name}; |
222 | my $answerResult = $pg->{answers}->{$name}; |
| 222 | my $studentAnswer = $answerResult->{student_ans}; # original_student_ans |
223 | my $studentAnswer = $answerResult->{student_ans}; # original_student_ans |
| 223 | my $preview = ($showAttemptPreview |
224 | my $preview = ($showAttemptPreview |
| 224 | ? $self->previewAnswer($answerResult, $imgGen) |
225 | ? $self->previewAnswer($answerResult, $imgGen, \$tthPreambleCache) |
| 225 | : ""); |
226 | : ""); |
| 226 | my $correctAnswer = $answerResult->{correct_ans}; |
227 | my $correctAnswer = $answerResult->{correct_ans}; |
| 227 | my $answerScore = $answerResult->{score}; |
228 | my $answerScore = $answerResult->{score}; |
| 228 | my $answerMessage = $showMessages ? $answerResult->{ans_message} : ""; |
229 | my $answerMessage = $showMessages ? $answerResult->{ans_message} : ""; |
| 229 | $answerMessage =~ s/\n/<BR>/g; |
230 | $answerMessage =~ s/\n/<BR>/g; |
| … | |
… | |
| 275 | . ($showSummary ? CGI::p({class=>'emphasis'},$summary) : ""); |
276 | . ($showSummary ? CGI::p({class=>'emphasis'},$summary) : ""); |
| 276 | } |
277 | } |
| 277 | |
278 | |
| 278 | |
279 | |
| 279 | sub previewAnswer { |
280 | sub previewAnswer { |
| 280 | my ($self, $answerResult, $imgGen) = @_; |
281 | my ($self, $answerResult, $imgGen, $tthPreambleCache) = @_; |
| 281 | my $ce = $self->r->ce; |
282 | my $ce = $self->r->ce; |
| 282 | my $effectiveUser = $self->{effectiveUser}; |
283 | my $effectiveUser = $self->{effectiveUser}; |
| 283 | my $set = $self->{set}; |
284 | my $set = $self->{set}; |
| 284 | my $problem = $self->{problem}; |
285 | my $problem = $self->{problem}; |
| 285 | my $displayMode = $self->{displayMode}; |
286 | my $displayMode = $self->{displayMode}; |
| … | |
… | |
| 294 | return "" unless defined $tex and $tex ne ""; |
295 | return "" unless defined $tex and $tex ne ""; |
| 295 | |
296 | |
| 296 | if ($displayMode eq "plainText") { |
297 | if ($displayMode eq "plainText") { |
| 297 | return $tex; |
298 | return $tex; |
| 298 | } elsif ($displayMode eq "formattedText") { |
299 | } elsif ($displayMode eq "formattedText") { |
|
|
300 | |
|
|
301 | # read the TTH preamble, or use the cached copy passed in from the caller |
|
|
302 | my $tthPreamble; |
|
|
303 | if (defined $$tthPreambleCache) { |
|
|
304 | $tthPreamble = $$tthPreambleCache; |
|
|
305 | } else { |
|
|
306 | my $tthPreambleFile = $ce->{courseDirs}->{templates} . "/tthPreamble.tex"; |
|
|
307 | if (-r $tthPreambleFile) { |
|
|
308 | $tthPreamble = readFile($tthPreambleFile); |
|
|
309 | # thanks to Jim Martino. each line in the definition file should end with |
|
|
310 | #a % to prevent adding supurious paragraphs to output: |
|
|
311 | $tthPreamble =~ s/(.)\n/$1%\n/g; |
|
|
312 | # solves the problem if the file doesn't end with a return: |
|
|
313 | $tthPreamble .="%\n"; |
|
|
314 | # store preamble in cache: |
|
|
315 | $$tthPreambleCache = $tthPreamble; |
|
|
316 | } else { |
|
|
317 | } |
|
|
318 | } |
|
|
319 | |
|
|
320 | # construct TTH command line |
| 299 | my $tthCommand = $ce->{externalPrograms}->{tth} |
321 | my $tthCommand = $ce->{externalPrograms}->{tth} |
| 300 | . " -L -f5 -r 2> /dev/null <<END_OF_INPUT; echo > /dev/null\n" |
322 | . " -L -f5 -r 2> /dev/null <<END_OF_INPUT; echo > /dev/null\n" |
| 301 | . "\\(".$tex."\\)\n" |
323 | . $tthPreamble . "\\(" . $tex . "\\)\n" |
| 302 | . "END_OF_INPUT\n"; |
324 | . "END_OF_INPUT\n"; |
| 303 | |
325 | |
| 304 | # call tth |
326 | # call tth |
| 305 | my $result = `$tthCommand`; |
327 | my $result = `$tthCommand`; |
| 306 | if ($?) { |
328 | if ($?) { |
| 307 | return "<b>[tth failed: $? $@]</b>"; |
329 | return "<b>[tth failed: $? $@]</b>"; |
| 308 | } else { |
330 | } else { |
| 309 | return $result; |
331 | return $result; |
| 310 | } |
332 | } |
|
|
333 | |
| 311 | } elsif ($displayMode eq "images") { |
334 | } elsif ($displayMode eq "images") { |
| 312 | $imgGen->add($tex); |
335 | $imgGen->add($tex); |
| 313 | } elsif ($displayMode eq "jsMath") { |
336 | } elsif ($displayMode eq "jsMath") { |
| 314 | return '<SPAN CLASS="math">\\displaystyle{'.$tex.'}</SPAN>'; |
337 | return '<SPAN CLASS="math">\\displaystyle{'.$tex.'}</SPAN>'; |
| 315 | } |
338 | } |