[system] / branches / rel-2-4-patches / webwork2 / lib / WeBWorK / PG.pm Repository:
ViewVC logotype

Diff of /branches/rel-2-4-patches/webwork2/lib/WeBWorK/PG.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 919 Revision 2217
1################################################################################ 1################################################################################
2# WeBWorK mod_perl (c) 2000-2002 WeBWorK Project 2# WeBWorK Online Homework Delivery System
3# $Id$ 3# Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: webwork-modperl/lib/WeBWorK/PG.pm,v 1.51 2004/05/24 02:01:25 dpvc Exp $
5#
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
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.
10#
11# This program is distributed in the hope that it will be useful, but WITHOUT
12# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the
14# Artistic License for more details.
4################################################################################ 15################################################################################
5 16
6package WeBWorK::PG; 17package WeBWorK::PG;
7 18
8=head1 NAME 19=head1 NAME
9 20
10WeBWorK::PG - Wrap the action of the PG Translator in an easy-to-use API. 21WeBWorK::PG - Invoke one of several PG rendering methods using an easy-to-use
22API.
11 23
12=cut 24=cut
13 25
14use strict; 26use strict;
15use warnings; 27use warnings;
16use File::Path qw(rmtree);
17use File::Temp qw(tempdir);
18use WeBWorK::PG::Translator; 28use WeBWorK::PG::ImageGenerator;
19use WeBWorK::Utils qw(readFile formatDateTime writeTimingLogEntry); 29use WeBWorK::Utils qw(runtime_use formatDateTime makeTempDirectory);
20 30
21sub new($$$$$$$$) { 31use constant DISPLAY_MODES => {
22 my $invocant = shift; 32 # display name # mode name
23 my $class = ref($invocant) || $invocant; 33 tex => "TeX",
34 plainText => "HTML",
35 formattedText => "HTML_tth",
36 images => "HTML_dpng",
37 jsMath => "HTML_jsMath",
38 asciimath => "HTML_asciimath",
39};
40
41use constant DISPLAY_MODE_FAILOVER => {
42 TeX => [],
43 HTML => [],
44 HTML_tth => [ "HTML", ],
45 HTML_dpng => [ "HTML_tth", "HTML", ],
46 HTML_jsMath => [ "HTML_dpng", "HTML_tth", "HTML", ],
47 HTML_asciimath => [ "HTML_dpng", "HTML_tth", "HTML", ],
48 # legacy modes -- these are not supported, but some problems might try to
49 # set the display mode to one of these values manually and some macros may
50 # provide rendered versions for these modes but not the one we want.
51 Latex2HTML => [ "TeX", "HTML", ],
52 HTML_img => [ "HTML_dpng", "HTML_tth", "HTML", ],
53};
54
55sub new {
56 shift; # throw away invocant -- we don't need it
57 my ($ce, $user, $key, $set, $problem, $psvn, $formFields,
58 $translationOptions) = @_;
59
60 my $renderer = $ce->{pg}->{renderer};
61
62 runtime_use $renderer;
63
64 return $renderer->new(@_);
65}
66
67sub defineProblemEnvir {
24 my ( 68 my (
25 $courseEnv,
26 $user,
27 $key,
28 $set, 69 $self,
29 $problem,
30 $psvn,
31 $formFields, # in CGI::Vars format
32 $translationOptions, # hashref containing options for the
33 # translator, such as whether to show
34 # hints and the display mode to use
35 ) = @_;
36
37 # write timing log entry
38 writeTimingLogEntry($courseEnv, "WeBWorK::PG::new",
39 "user=".$user->user_id.",problem=".$courseEnv->{courseName}."/".$set->set_id."/".$problem->problem_id.",mode=".$translationOptions->{displayMode},
40 "begin");
41
42 # install a local warn handler to collect warnings
43 my $warnings = "";
44 local $SIG{__WARN__} = sub { $warnings .= shift }
45 if $courseEnv->{pg}->{options}->{catchWarnings};
46
47 # create a Translator
48 #warn "PG: creating a Translator\n";
49 my $translator = WeBWorK::PG::Translator->new;
50
51 # set the directory hash
52 #warn "PG: setting the directory hash\n";
53 $translator->rh_directories({
54 courseScriptsDirectory => $courseEnv->{webworkDirs}->{macros},
55 macroDirectory => $courseEnv->{courseDirs}->{macros},
56 templateDirectory => $courseEnv->{courseDirs}->{templates},
57 tempDirectory => $courseEnv->{courseDirs}->{html_temp},
58 });
59
60 # evaluate modules and "extra packages"
61 #warn "PG: evaluating modules and \"extra packages\"\n";
62 my @modules = @{ $courseEnv->{pg}->{modules} };
63 foreach my $module_packages_ref (@modules) {
64 my ($module, @extra_packages) = @$module_packages_ref;
65 # the first item is the main package
66 $translator->evaluate_modules($module);
67 # the remaining items are "extra" packages
68 $translator->load_extra_packages(@extra_packages);
69 }
70
71 # set the environment (from defineProblemEnvir)
72 #warn "PG: setting the environment (from defineProblemEnvir)\n";
73 my $envir = defineProblemEnvir(
74 $courseEnv,
75 $user,
76 $key, 70 $ce,
77 $set,
78 $problem,
79 $psvn,
80 $formFields,
81 $translationOptions,
82 );
83 $translator->environment($envir);
84
85 # initialize the Translator
86 #warn "PG: initializing the Translator\n";
87 $translator->initialize();
88
89 # load IO.pl, PG.pl, and dangerousMacros.pl using unrestricted_load
90 # i'd like to change this at some point to have the same sort of interface to global.conf
91 # that the module loading does -- have a list of macros to load unrestrictedly.
92 #warn "PG: loading IO.pl, PG.pl, and dangerousMacros.pl using unrestricted_load\n";
93 foreach (qw(IO.pl PG.pl dangerousMacros.pl)) {
94 my $macroPath = $courseEnv->{webworkDirs}->{macros} . "/$_";
95 my $err = $translator->unrestricted_load($macroPath);
96 warn "Error while loading $macroPath: $err" if $err;
97 }
98
99 # set the opcode mask (using default values)
100 #warn "PG: setting the opcode mask (using default values)\n";
101 $translator->set_mask();
102
103 # store the problem source
104 #warn "PG: storing the problem source\n";
105 my $sourceFile = $problem->source_file;
106 $sourceFile = $courseEnv->{courseDirs}->{templates}."/".$sourceFile
107 unless ($sourceFile =~ /^\//);
108 eval { $translator->source_string(readFile($sourceFile)) };
109 if ($@) {
110 # well, we couldn't get the problem source, for some reason.
111 return bless {
112 translator => $translator,
113 head_text => "",
114 body_text => <<EOF,
115WeBWorK::Utils::readFile($sourceFile) says:
116$@
117EOF
118 answers => {},
119 result => {},
120 state => {},
121 errors => "Failed to read the problem source file.",
122 warnings => $warnings,
123 flags => {error_flag => 1},
124 }, $class;
125 }
126
127 # install a safety filter (&safetyFilter)
128 #warn "PG: installing a safety filter\n";
129 $translator->rf_safety_filter(\&safetyFilter);
130
131 # write timing log entry -- the translator is now all set up
132 writeTimingLogEntry($courseEnv, "WeBWorK::PG::new",
133 "initialized",
134 "intermediate");
135
136 # translate the PG source into text
137 #warn "PG: translating the PG source into text\n";
138 $translator->translate();
139
140 # after we're done translating, we may have to clean up after the translator.
141 # for example, 'images' mode uses a tempdir for dvipng's temp files. We have
142 # to remove it.
143 if ($translationOptions->{displayMode} eq 'images' && $envir->{dvipngTempDir}) {
144 rmtree($envir->{dvipngTempDir}, 0, 0);
145 }
146
147 my ($result, $state); # we'll need these on the other side of the if block!
148 if ($translationOptions->{processAnswers}) {
149
150 # process student answers
151 #warn "PG: processing student answers\n";
152 $translator->process_answers($formFields);
153
154 # retrieve the problem state and give it to the translator
155 #warn "PG: retrieving the problem state and giving it to the translator\n";
156 $translator->rh_problem_state({
157 recorded_score => $problem->status,
158 num_of_correct_ans => $problem->num_correct,
159 num_of_incorrect_ans => $problem->num_incorrect,
160 });
161
162 # determine an entry order -- the ANSWER_ENTRY_ORDER flag is built by
163 # the PG macro package (PG.pl)
164 #warn "PG: determining an entry order\n";
165 my @answerOrder =
166 $translator->rh_flags->{ANSWER_ENTRY_ORDER}
167 ? @{ $translator->rh_flags->{ANSWER_ENTRY_ORDER} }
168 : keys %{ $translator->rh_evaluated_answers };
169
170 # install a grader -- use the one specified in the problem,
171 # or fall back on the default from the course environment.
172 # (two magic strings are accepted, to avoid having to
173 # reference code when it would be difficult.)
174 #warn "PG: installing a grader\n";
175 my $grader = $translator->rh_flags->{PROBLEM_GRADER_TO_USE}
176 || $courseEnv->{pg}->{options}->{grader};
177 $grader = $translator->rf_std_problem_grader
178 if $grader eq "std_problem_grader";
179 $grader = $translator->rf_avg_problem_grader
180 if $grader eq "avg_problem_grader";
181 die "Problem grader $grader is not a CODE reference."
182 unless ref $grader eq "CODE";
183 $translator->rf_problem_grader($grader);
184
185 # grade the problem
186 #warn "PG: grading the problem\n";
187 ($result, $state) = $translator->grade_problem(
188 answers_submitted => $translationOptions->{processAnswers},
189 ANSWER_ENTRY_ORDER => \@answerOrder,
190 );
191
192 }
193
194 # write timing log entry
195 writeTimingLogEntry($courseEnv, "WeBWorK::PG::new", "", "end");
196
197 # return an object which contains the translator and the results of
198 # the translation process. this is DIFFERENT from the "format expected
199 # by Webwork.pm (and I believe processProblem8, but check.)"
200 return bless {
201 translator => $translator,
202 head_text => ${ $translator->r_header },
203 body_text => ${ $translator->r_text },
204 answers => $translator->rh_evaluated_answers,
205 result => $result,
206 state => $state,
207 errors => $translator->errors,
208 warnings => $warnings,
209 flags => $translator->rh_flags,
210 }, $class;
211}
212
213# -----
214
215sub defineProblemEnvir($$$$$$$) {
216 my (
217 $courseEnv,
218 $user, 71 $user,
219 $key, 72 $key,
220 $set, 73 $set,
221 $problem, 74 $problem,
222 $psvn, 75 $psvn,
224 $options, 77 $options,
225 ) = @_; 78 ) = @_;
226 79
227 my %envir; 80 my %envir;
228 81
82 # ----------------------------------------------------------------------
83
229 # PG environment variables 84 # PG environment variables
230 # from docs/pglanguage/pgreference/environmentvariables as of 06/25/2002 85 # from docs/pglanguage/pgreference/environmentvariables as of 06/25/2002
231 # any changes are noted by "ADDED:" or "REMOVED:" 86 # any changes are noted by "ADDED:" or "REMOVED:"
232 87
233 # Vital state information 88 # Vital state information
234 # ADDED: displayHintsQ, displaySolutionsQ, refreshMath2img, 89 # ADDED: displayModeFailover, displayHintsQ, displaySolutionsQ,
235 # texDisposition 90 # refreshMath2img, texDisposition
236 91
237 $envir{psvn} = $psvn; 92 $envir{psvn} = $set->psvn;
238 $envir{psvnNumber} = $envir{psvn}; 93 $envir{psvnNumber} = $envir{psvn};
239 $envir{probNum} = $problem->problem_id; 94 $envir{probNum} = $problem->problem_id;
240 $envir{questionNumber} = $envir{probNum}; 95 $envir{questionNumber} = $envir{probNum};
241 $envir{fileName} = $problem->source_file; 96 $envir{fileName} = $problem->source_file;
242 $envir{probFileName} = $envir{fileName}; 97 $envir{probFileName} = $envir{fileName};
243 $envir{problemSeed} = $problem->problem_seed; 98 $envir{problemSeed} = $problem->problem_seed;
244 $envir{displayMode} = translateDisplayModeNames($options->{displayMode}); 99 $envir{displayMode} = translateDisplayModeNames($options->{displayMode});
245 $envir{languageMode} = $envir{displayMode}; 100 $envir{languageMode} = $envir{displayMode};
246 $envir{outputMode} = $envir{displayMode}; 101 $envir{outputMode} = $envir{displayMode};
102 $envir{displayModeFailover} = DISPLAY_MODE_FAILOVER();
247 $envir{displayHintsQ} = $options->{showHints}; 103 $envir{displayHintsQ} = $options->{showHints};
248 $envir{displaySolutionsQ} = $options->{showSolutions}; 104 $envir{displaySolutionsQ} = $options->{showSolutions};
249 $envir{refreshMath2img} = $options->{refreshMath2img};
250 $envir{texDisposition} = "pdf"; # in webwork-modperl, we use pdflatex 105 $envir{texDisposition} = "pdf"; # in webwork2, we use pdflatex
251 106
252 # Problem Information 107 # Problem Information
253 # ADDED: courseName, formatedDueDate 108 # ADDED: courseName, formatedDueDate
254 109
255 $envir{openDate} = $set->open_date; 110 $envir{openDate} = $set->open_date;
260 $envir{answerDate} = $set->answer_date; 115 $envir{answerDate} = $set->answer_date;
261 $envir{formattedAnswerDate} = formatDateTime($envir{answerDate}); 116 $envir{formattedAnswerDate} = formatDateTime($envir{answerDate});
262 $envir{numOfAttempts} = ($problem->num_correct || 0) + ($problem->num_incorrect || 0); 117 $envir{numOfAttempts} = ($problem->num_correct || 0) + ($problem->num_incorrect || 0);
263 $envir{problemValue} = $problem->value; 118 $envir{problemValue} = $problem->value;
264 $envir{sessionKey} = $key; 119 $envir{sessionKey} = $key;
265 $envir{courseName} = $courseEnv->{courseName}; 120 $envir{courseName} = $ce->{courseName};
266 121
267 # Student Information 122 # Student Information
268 # ADDED: studentID 123 # ADDED: studentID
269 124
270 $envir{sectionName} = $user->section; 125 $envir{sectionName} = $user->section;
283 138
284 # External Programs 139 # External Programs
285 # ADDED: externalLaTeXPath, externalDvipngPath, 140 # ADDED: externalLaTeXPath, externalDvipngPath,
286 # externalGif2EpsPath, externalPng2EpsPath 141 # externalGif2EpsPath, externalPng2EpsPath
287 142
288 $envir{externalTTHPath} = $courseEnv->{externalPrograms}->{tth}; 143 $envir{externalTTHPath} = $ce->{externalPrograms}->{tth};
289 $envir{externalLaTeXPath} = $courseEnv->{externalPrograms}->{latex}; 144 $envir{externalLaTeXPath} = $ce->{externalPrograms}->{latex};
290 $envir{externalDvipngPath} = $courseEnv->{externalPrograms}->{dvipng}; 145 $envir{externalDvipngPath} = $ce->{externalPrograms}->{dvipng};
291 $envir{externalGif2EpsPath} = $courseEnv->{externalPrograms}->{gif2eps}; 146 $envir{externalGif2EpsPath} = $ce->{externalPrograms}->{gif2eps};
292 $envir{externalPng2EpsPath} = $courseEnv->{externalPrograms}->{png2eps}; 147 $envir{externalPng2EpsPath} = $ce->{externalPrograms}->{png2eps};
293 $envir{externalGif2PngPath} = $courseEnv->{externalPrograms}->{gif2png}; 148 $envir{externalGif2PngPath} = $ce->{externalPrograms}->{gif2png};
294 149
295 # Directories and URLs 150 # Directories and URLs
296 # REMOVED: courseName 151 # REMOVED: courseName
297 # ADDED: dvipngTempDir 152 # ADDED: dvipngTempDir
153 # ADDED: jsMathURL
154 # ADDED: asciimathURL
298 155
299 $envir{cgiDirectory} = undef; 156 $envir{cgiDirectory} = undef;
300 $envir{cgiURL} = undef; 157 $envir{cgiURL} = undef;
301 $envir{classDirectory} = undef; 158 $envir{classDirectory} = undef;
302 $envir{courseScriptsDirectory} = $courseEnv->{webworkDirs}->{macros}."/"; 159 $envir{courseScriptsDirectory} = $ce->{pg}->{directories}->{macros}."/";
303 $envir{htmlDirectory} = $courseEnv->{courseDirs}->{html}."/"; 160 $envir{htmlDirectory} = $ce->{courseDirs}->{html}."/";
304 $envir{htmlURL} = $courseEnv->{courseURLs}->{html}."/"; 161 $envir{htmlURL} = $ce->{courseURLs}->{html}."/";
305 $envir{macroDirectory} = $courseEnv->{courseDirs}->{macros}."/"; 162 $envir{macroDirectory} = $ce->{courseDirs}->{macros}."/";
306 $envir{templateDirectory} = $courseEnv->{courseDirs}->{templates}."/"; 163 $envir{templateDirectory} = $ce->{courseDirs}->{templates}."/";
307 $envir{tempDirectory} = $courseEnv->{courseDirs}->{html_temp}."/"; 164 $envir{tempDirectory} = $ce->{courseDirs}->{html_temp}."/";
308 $envir{tempURL} = $courseEnv->{courseURLs}->{html_temp}."/"; 165 $envir{tempURL} = $ce->{courseURLs}->{html_temp}."/";
309 $envir{scriptDirectory} = undef; 166 $envir{scriptDirectory} = undef;
310 $envir{webworkDocsURL} = $courseEnv->{webworkURLs}->{docs}."/"; 167 $envir{webworkDocsURL} = $ce->{webworkURLs}->{docs}."/";
311 $envir{dvipngTempDir} = $options->{displayMode} eq 'images' 168 $envir{localHelpURL} = $ce->{webworkURLs}->{local_help}."/";
312 ? tempdir("webwork-dvipng-XXXXXXXX", DIR => $envir{tempDirectory}) 169 $envir{jsMathURL} = $ce->{webworkURLs}->{jsMath};
313 : undef; 170 $envir{asciimathURL} = $ce->{webworkURLs}->{asciimath};
314 171
315 # Information for sending mail 172 # Information for sending mail
316 173
317 $envir{mailSmtpServer} = $courseEnv->{mail}->{smtpServer}; 174 $envir{mailSmtpServer} = $ce->{mail}->{smtpServer};
318 $envir{mailSmtpSender} = $courseEnv->{mail}->{smtpSender}; 175 $envir{mailSmtpSender} = $ce->{mail}->{smtpSender};
319 $envir{ALLOW_MAIL_TO} = $courseEnv->{mail}->{allowedRecipients}; 176 $envir{ALLOW_MAIL_TO} = $ce->{mail}->{allowedRecipients};
320 177
321 # Default values for evaluating answers 178 # Default values for evaluating answers
322 179
323 my $ansEvalDefaults = $courseEnv->{pg}->{ansEvalDefaults}; 180 my $ansEvalDefaults = $ce->{pg}->{ansEvalDefaults};
324 $envir{$_} = $ansEvalDefaults->{$_} foreach (keys %$ansEvalDefaults); 181 $envir{$_} = $ansEvalDefaults->{$_} foreach (keys %$ansEvalDefaults);
325 182
183 # ----------------------------------------------------------------------
184
185 my $basename = "equation-$envir{psvn}.$envir{probNum}";
186 $basename .= ".$envir{problemSeed}" if $envir{problemSeed};
187
188 # Object for generating equation images
189 $envir{imagegen} = WeBWorK::PG::ImageGenerator->new(
190 tempDir => $ce->{webworkDirs}->{tmp}, # global temp dir
191 latex => $envir{externalLaTeXPath},
192 dvipng => $envir{externalDvipngPath},
193 useCache => 1,
194 cacheDir => $ce->{webworkDirs}->{equationCache},
195 cacheURL => $ce->{webworkURLs}->{equationCache},
196 cacheDB => $ce->{webworkFiles}->{equationCacheDB},
197 );
198
326 # Other things... 199 # Other things...
327 200 $envir{QUIZ_PREFIX} = $options->{QUIZ_PREFIX}; # used by quizzes
328 $envir{PROBLEM_GRADER_TO_USE} = $courseEnv->{pg}->{options}->{grader}; 201 $envir{PROBLEM_GRADER_TO_USE} = $ce->{pg}->{options}->{grader};
202 $envir{PRINT_FILE_NAMES_FOR} = $ce->{pg}->{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR};
203
204 # variables for interpreting capa problems and other things to be
205 # seen in a pg file
206 my $specialPGEnvironmentVarHash = $ce->{pg}->{specialPGEnvironmentVars};
207 for my $SPGEV (keys %{$specialPGEnvironmentVarHash}) {
208 $envir{$SPGEV} = $specialPGEnvironmentVarHash->{$SPGEV};
209 }
329 210
330 return \%envir; 211 return \%envir;
331} 212}
332 213
333sub translateDisplayModeNames($) { 214sub translateDisplayModeNames($) {
334 my $name = shift; 215 my $name = shift;
335 return { 216 return DISPLAY_MODES()->{$name};
336 tex => "TeX",
337 plainText => "HTML",
338 formattedText => "HTML_tth",
339 images => "HTML_img"
340 }->{$name};
341} 217}
342 218
343sub safetyFilter { 219sub oldSafetyFilter {
344 my $answer = shift; # accepts one answer and checks it 220 my $answer = shift; # accepts one answer and checks it
345 my $submittedAnswer = $answer; 221 my $submittedAnswer = $answer;
346 $answer = '' unless defined $answer; 222 $answer = '' unless defined $answer;
347 my ($errorno); 223 my ($errorno);
348 $answer =~ tr/\000-\037/ /; 224 $answer =~ tr/\000-\037/ /;
353 return ($answer,$errorno); 229 return ($answer,$errorno);
354 } 230 }
355 # replace ^ with ** (for exponentiation) 231 # replace ^ with ** (for exponentiation)
356 # $answer =~ s/\^/**/g; 232 # $answer =~ s/\^/**/g;
357 # Return if forbidden characters are found 233 # Return if forbidden characters are found
358 unless ($answer =~ /^[a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)]+$/ ) { 234 unless ($answer =~ /^[a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\[\]\(\)\,\|]+$/ ) {
359 $answer =~ tr/a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)/#/c; 235 $answer =~ tr/a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)/#/c;
360 $errorno = "<BR>There are forbidden characters in your answer: $submittedAnswer<BR>"; 236 $errorno = "<BR>There are forbidden characters in your answer: $submittedAnswer<BR>";
361 return ($answer,$errorno); 237 return ($answer,$errorno);
362 } 238 }
363 $errorno = 0; 239 $errorno = 0;
364 return($answer, $errorno); 240 return($answer, $errorno);
365} 241}
366 242
243sub nullSafetyFilter {
244 return shift, 0; # no errors
245}
246
3671; 2471;
368 248
369__END__ 249__END__
370 250
371=head1 SYNOPSIS 251=head1 SYNOPSIS
372 252
373 $pg = WeBWorK::PG->new( 253 $pg = WeBWorK::PG->new(
374 $courseEnv, # a WeBWorK::CourseEnvironment object 254 $ce, # a WeBWorK::CourseEnvironment object
375 $user, # a WeBWorK::DB::Record::User object 255 $user, # a WeBWorK::DB::Record::User object
376 $sessionKey, 256 $sessionKey,
377 $set, # a WeBWorK::DB::Record::UserSet object 257 $set, # a WeBWorK::DB::Record::UserSet object
378 $problem, # a WeBWorK::DB::Record::UserProblem object 258 $problem, # a WeBWorK::DB::Record::UserProblem object
379 $psvn, 259 $psvn,
397 $warnings = $pg->{warnings}; # text string 277 $warnings = $pg->{warnings}; # text string
398 $flags = $pg->{flags}; # hash reference 278 $flags = $pg->{flags}; # hash reference
399 279
400=head1 DESCRIPTION 280=head1 DESCRIPTION
401 281
402WeBWorK::PG encapsulates the PG translation process, making multiple calls to 282WeBWorK::PG is a factory for modules which use the WeBWorK::PG API. Notable
403WeBWorK::PG::Translator. Much of the flexibility of the Translator is hidden, 283modules which use this API (and exist) are WeBWorK::PG::Local and
404instead making choices that are appropriate for the webwork-modperl system. 284WeBWorK::PG::Remote. The course environment key $pg{renderer} is consulted to
285determine which render to use.
405 286
406=head1 CONSTRUCTION 287=head1 THE WEBWORK::PG API
288
289Modules which support this API must implement the following method:
407 290
408=over 291=over
409 292
410=item new (ENVIRONMENT, USER, KEY, SET, PROBLEM, PSVN, FIELDS, OPTIONS) 293=item new ENVIRONMENT, USER, KEY, SET, PROBLEM, PSVN, FIELDS, OPTIONS
411 294
412The C<new> method creates a translator, initializes it using the parameters 295The C<new> method creates a translator, initializes it using the parameters
413specified, translates a PG file, and processes answers. It returns a reference 296specified, translates a PG file, and processes answers. It returns a reference
414to a blessed hash containing the results of the translation process. 297to a blessed hash containing the results of the translation process.
415 298
471boolean, render solutions 354boolean, render solutions
472 355
473=item refreshMath2img 356=item refreshMath2img
474 357
475boolean, force images created by math2img (in "images" mode) to be recreated, 358boolean, force images created by math2img (in "images" mode) to be recreated,
476even if the PG source has not been updated. 359even if the PG source has not been updated. FIXME: remove this option.
477 360
478=item processAnswers 361=item processAnswers
479 362
480boolean, call answer evaluators and graders 363boolean, call answer evaluators and graders
481 364
529 412
530A hash containing PG_flags (see the Translator docs). 413A hash containing PG_flags (see the Translator docs).
531 414
532=back 415=back
533 416
534=head1 OPERATION 417=head1 METHODS PROVIDED BY THE BASE CLASS
535 418
536WeBWorK::PG goes through the following operations when constructed: 419The following methods are provided for use by subclasses of WeBWorK::PG.
537 420
538=over 421=over
539 422
540=item Get database information 423=item defineProblemEnvir ENVIRONMENT, USER, KEY, SET, PROBLEM, PSVN, FIELDS, OPTIONS
541 424
542Retrieve information about the current user, set, and problem from the 425Generate a problem environment hash to pass to the renderer.
543database.
544 426
545=item Create a translator 427=item translateDisplayModeNames NAME
546 428
547Instantiate a WeBWorK::PG::Translator object. 429NAME contains
548
549=item Set the directory hash
550
551Set the translator's directory hash (courseScripts, macros, templates, and temp
552directories) from the course environment.
553
554=item Evaluate PG modules
555
556Using the module list from the course environment (pg->modules), perform a
557"use"-like operation to evaluate modules at runtime.
558
559=item Set the problem environment
560
561Use data from the user, set, and problem, as well as the course environemnt and
562translation options, to set the problem environment.
563
564=item Initialize the translator
565
566Call &WeBWorK::PG::Translator::initialize. What more do you want?
567
568=item Load PG.pl and dangerousMacros.pl
569
570These macros must be loaded without opcode masking, so they are loaded here.
571
572=item Set the opcode mask
573
574Set the opcode mask to the default specified by WeBWorK::PG::Translator.
575
576=item Load the problem source
577
578Give the problem source to the translator.
579
580=item Install a safety filter
581
582The safety filter is used to preprocess student input before evaluation. The
583default safety filter, &WeBWorK::PG::safetyFilter, is used.
584
585=item Translate the problem source
586
587Call &WeBWorK::PG::Translator::translate to render the problem source into the
588format given by the display mode.
589
590=item Process student answers
591
592Use form field inputs to evaluate student answers.
593
594=item Load the problem state
595
596Use values from the database to initialize the problem state, so that the
597grader will have a point of reference.
598
599=item Determine an entry order
600
601Use the ANSWER_ENTRY_ORDER flag to determine the order of answers in the
602problem. This is important for problems with dependancies among parts.
603
604=item Install a grader
605
606Use the PROBLEM_GRADER_TO_USE flag, or a default from the course environment,
607to install a grader.
608
609=item Grade the problem
610
611Use the selected grader to grade the problem.
612 430
613=back 431=back
614 432
615=head1 AUTHOR 433=head1 AUTHOR
616 434

Legend:
Removed from v.919  
changed lines
  Added in v.2217

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9