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

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

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

Revision 492 Revision 4376
1################################################################################ 1################################################################################
2# WeBWorK mod_perl (c) 1995-2002 WeBWorK Team, Univeristy of Rochester 2# WeBWorK Online Homework Delivery System
3# $Id$ 3# Copyright © 2000-2006 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: webwork2/lib/WeBWorK/PG.pm,v 1.65 2006/05/23 20:47:27 gage 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 WeBWorK::DB::Classlist;
17use WeBWorK::DB::WW;
18use WeBWorK::PG::Translator; 28use WeBWorK::PG::ImageGenerator;
19use WeBWorK::Problem; 29use WeBWorK::Utils qw(runtime_use formatDateTime makeTempDirectory);
20use WeBWorK::Utils qw(readFile formatDateTime);
21 30
22sub new($$$$$$$$) { 31use constant DISPLAY_MODES => {
23 my $invocant = shift; 32 # display name # mode name
24 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
41sub new {
42 shift; # throw away invocant -- we don't need it
43 my ($ce, $user, $key, $set, $problem, $psvn, $formFields,
44 $translationOptions) = @_;
45
46 my $renderer = $ce->{pg}->{renderer};
47
48 runtime_use $renderer;
49
50 return $renderer->new(@_);
51}
52
53sub defineProblemEnvir {
25 my ( 54 my (
26 $courseEnv, 55 $self,
27 $userName,
28 $key, 56 $ce,
29 $setName,
30 $problemNumber,
31 $translationOptions, # hashref containing options for the
32 # translator, such as whether to show
33 # hints and the display mode to use
34 $formFields, # in CGI::Vars format
35 ) = @_;
36
37 # get database information
38 my $classlist = WeBWorK::DB::Classlist->new($courseEnv);
39 my $wwdb = WeBWorK::DB::WW->new($courseEnv);
40 my $user = $classlist->getUser($userName);
41 my $set = $wwdb->getSet($userName, $setName);
42 my $psvn = $wwdb->getPSVN($userName, $setName);
43
44 my $problem;
45 if ($problemNumber =~ /^\d+$/) {
46 $problem = $wwdb->getProblem($userName, $setName, $problemNumber);
47 } else {
48 # This is the fun part: if $problemNumber is NON-NUMERIC, the
49 # user wants to specify a PG file directly. We manufacture a
50 # Problem object using fake data and the specified source file.
51 # This is potentially dangerous since an untrusted user is
52 # allowed to specifiy an arbitrary file to be evaluated as PG.
53 # A user of PG.pm MUST MAKE SURE that if $problemNumber is
54 # supplied by an untrusted source (i.e. the Apache request),
55 # it is numberic. A simple
56 #
57 # die unless $problemNumber =~ /^\d+$/;
58 #
59 # should suffice.
60 $problem = WeBWorK::Problem->new(
61 id => 0,
62 set_id => $set->id,
63 login_id => $user->id,
64 source_file => $problemNumber,
65 # the rest of Problem's fields are not needed
66 );
67 }
68
69 # create a Translator
70 warn "PG: creating a Translator\n";
71 my $translator = WeBWorK::PG::Translator->new;
72
73 # set the directory hash
74 warn "PG: setting the directory hash\n";
75 $translator->rh_directories({
76 courseScriptsDirectory => $courseEnv->{webworkDirs}->{macros},
77 macroDirectory => $courseEnv->{courseDirs}->{macros},
78 templateDirectory => $courseEnv->{courseDirs}->{templates},
79 tempDirectory => $courseEnv->{courseDirs}->{html_temp},
80 });
81
82 # evaluate modules and "extra packages"
83 warn "PG: evaluating modules and \"extra packages\"\n";
84 my @modules = @{ $courseEnv->{pg}->{modules} };
85 foreach my $module_packages_ref (@modules) {
86 my ($module, @extra_packages) = @$module_packages_ref;
87 # the first item is the main package
88 $translator->evaluate_modules($module);
89 # the remaining items are "extra" packages
90 $translator->load_extra_packages(@extra_packages);
91 }
92
93 # set the environment (from defineProblemEnvir)
94 warn "PG: setting the environment (from defineProblemEnvir)\n";
95 $translator->environment(defineProblemEnvir(
96 $courseEnv, $user, $key, $set, $problem, $psvn, $formFields, $translationOptions));
97
98 # initialize the Translator
99 warn "PG: initializing the Translator\n";
100 $translator->initialize();
101
102 # load PG.pl and dangerousMacros.pl using unrestricted_load
103 # i'd like to change this at some point to have the same sort of interface to global.conf
104 # that the module loading does -- have a list of macros to load unrestrictedly.
105 warn "PG: loading PG.pl and dangerousMacros.pl using unrestricted_load\n";
106 my $pg_pl = $courseEnv->{webworkDirs}->{macros} . "/PG.pl";
107 my $dangerousMacros_pl = $courseEnv->{webworkDirs}->{macros} . "/dangerousMacros.pl";
108 my $err = $translator->unrestricted_load($pg_pl);
109 warn "Error while loading $pg_pl: $err" if $err;
110 $err = $translator->unrestricted_load($dangerousMacros_pl);
111 warn "Error while loading $dangerousMacros_pl: $err" if $err;
112
113 # set the opcode mask (using default values)
114 warn "PG: setting the opcode mask (using default values)\n";
115 $translator->set_mask();
116
117 # store the problem source
118 warn "PG: storing the problem source\n";
119 my $sourceFile = $problem->source_file;
120 $sourceFile = $courseEnv->{courseDirs}->{templates}."/".$sourceFile
121 unless ($sourceFile =~ /^\//);
122 $translator->source_string(readFile($sourceFile));
123
124 # install a safety filter (&safetyFilter)
125 warn "PG: installing a safety filter\n";
126 $translator->rf_safety_filter(\&safetyFilter);
127
128 # translate the PG source into text
129 warn "PG: translating the PG source into text\n";
130 $translator->translate();
131
132 my ($result, $state); # we'll need these on the other side of the if block!
133 if ($translationOptions->{processAnswers}) {
134
135 # process student answers
136 warn "PG: processing student answers\n";
137 $translator->process_answers($formFields);
138
139 # retrieve the problem state and give it to the translator
140 warn "PG: retrieving the problem state and giving it to the translator\n";
141 $translator->rh_problem_state({
142 recorded_score => $problem->status,
143 num_of_correct_ans => $problem->num_correct,
144 num_of_incorrect_ans => $problem->num_incorrect,
145 });
146
147 # determine an entry order -- the ANSWER_ENTRY_ORDER flag is built by
148 # the PG macro package (PG.pl)
149 warn "PG: determining an entry order\n";
150 my @answerOrder =
151 $translator->rh_flags->{ANSWER_ENTRY_ORDER}
152 ? @{ $translator->rh_flags->{ANSWER_ENTRY_ORDER} }
153 : keys %{ $translator->rh_evaluated_answers };
154
155 # install a grader -- use the one specified in the problem,
156 # or fall back on the default from the course environment.
157 # (two magic strings are accepted, to avoid having to
158 # reference code when it would be difficult.)
159 warn "PG: installing a grader\n";
160 my $grader = $translator->rh_flags->{PROBLEM_GRADER_TO_USE}
161 || $courseEnv->{pg}->{options}->{grader};
162 $grader = $translator->rf_std_problem_grader
163 if $grader eq "std_problem_grader";
164 $grader = $translator->rf_avg_problem_grader
165 if $grader eq "avg_problem_grader";
166 die "Problem grader $grader is not a CODE reference."
167 unless ref $grader eq "CODE";
168 $translator->rf_problem_grader($grader);
169
170 # grade the problem
171 warn "PG: grading the problem\n";
172 ($result, $state) = $translator->grade_problem(
173 answers_submitted => $translationOptions->{processAnswers},
174 ANSWER_ENTRY_ORDER => \@answerOrder,
175 );
176
177 }
178
179 # return an object which contains the translator and the results of
180 # the translation process. this is DIFFERENT from the "format expected
181 # by Webwork.pm (and I believe processProblem8, but check.)"
182 return bless {
183 translator => $translator,
184 head_text => ${ $translator->r_header },
185 body_text => ${ $translator->r_text },
186 answers => $translator->rh_evaluated_answers,
187 result => $result,
188 state => $state,
189 errors => $translator->errors, # *** what is this doing?
190 warnings => undef, # *** gotta catch warnings eventually...
191 flags => $translator->rh_flags,
192 }, $class;
193}
194
195# -----
196
197sub defineProblemEnvir($$$$$$$) {
198 my (
199 $courseEnv,
200 $user, 57 $user,
201 $key, 58 $key,
202 $set, 59 $set,
203 $problem, 60 $problem,
204 $psvn, 61 $psvn,
206 $options, 63 $options,
207 ) = @_; 64 ) = @_;
208 65
209 my %envir; 66 my %envir;
210 67
68 # ----------------------------------------------------------------------
69
211 # PG environment variables 70 # PG environment variables
212 # from docs/pglanguage/pgreference/environmentvariables as of 06/25/2002 71 # from docs/pglanguage/pgreference/environmentvariables as of 06/25/2002
213 # any changes are noted by "ADDED:" or "REMOVED:" 72 # any changes are noted by "ADDED:" or "REMOVED:"
214 73
215 # Vital state information 74 # Vital state information
216 # ADDED: displayHintsQ, displaySolutionsQ, refreshMath2img 75 # ADDED: displayModeFailover, displayHintsQ, displaySolutionsQ,
76 # refreshMath2img, texDisposition
217 77
218 $envir{psvn} = $psvn; 78 $envir{psvn} = $set->psvn;
219 $envir{psvnNumber} = $envir{psvn}; 79 $envir{psvnNumber} = $envir{psvn};
220 $envir{probNum} = $problem->id; 80 $envir{probNum} = $problem->problem_id;
221 $envir{questionNumber} = $envir{probNum}; 81 $envir{questionNumber} = $envir{probNum};
222 $envir{fileName} = $problem->source_file; 82 $envir{fileName} = $problem->source_file;
223 $envir{probFileName} = $envir{fileName}; 83 $envir{probFileName} = $envir{fileName};
224 $envir{problemSeed} = $problem->problem_seed; 84 $envir{problemSeed} = $problem->problem_seed;
225 $envir{displayMode} = translateDisplayModeNames($options->{displayMode}); 85 $envir{displayMode} = translateDisplayModeNames($options->{displayMode});
226 $envir{languageMode} = $envir{displayMode}; 86 $envir{languageMode} = $envir{displayMode};
227 $envir{outputMode} = $envir{displayMode}; 87 $envir{outputMode} = $envir{displayMode};
228 $envir{displayHintsQ} = $options->{hints}; 88 $envir{displayHintsQ} = $options->{showHints};
229 $envir{displaySolutionsQ} = $options->{solutions}; 89 $envir{displaySolutionsQ} = $options->{showSolutions};
230 $envir{refreshMath2img} = $options->{refreshMath2img}; 90 $envir{texDisposition} = "pdf"; # in webwork2, we use pdflatex
231 91
232 # Problem Information 92 # Problem Information
233 # ADDED: courseName 93 # ADDED: courseName, formatedDueDate
234 94
235 $envir{openDate} = $set->open_date; 95 $envir{openDate} = $set->open_date;
236 $envir{formattedOpenDate} = formatDateTime($envir{openDate}); 96 $envir{formattedOpenDate} = formatDateTime($envir{openDate}, $ce->{siteDefaults}{timezone});
237 $envir{dueDate} = $set->due_date; 97 $envir{dueDate} = $set->due_date;
238 $envir{formattedDueDate} = formatDateTime($envir{dueDate}); 98 $envir{formattedDueDate} = formatDateTime($envir{dueDate}, $ce->{siteDefaults}{timezone});
99 $envir{formatedDueDate} = $envir{formattedDueDate}; # typo in many header files
239 $envir{answerDate} = $set->answer_date; 100 $envir{answerDate} = $set->answer_date;
240 $envir{formattedAnswerDate} = formatDateTime($envir{answerDate}); 101 $envir{formattedAnswerDate} = formatDateTime($envir{answerDate}, $ce->{siteDefaults}{timezone});
241 $envir{numOfAttempts} = $problem->num_correct + $problem->num_incorrect; 102 $envir{numOfAttempts} = ($problem->num_correct || 0) + ($problem->num_incorrect || 0);
242 $envir{problemValue} = $problem->value; 103 $envir{problemValue} = $problem->value;
243 $envir{sessionKey} = $key; 104 $envir{sessionKey} = $key;
244 $envir{courseName} = $courseEnv->{courseName}; 105 $envir{courseName} = $ce->{courseName};
245 106
246 # Student Information 107 # Student Information
247 # ADDED: studentID 108 # ADDED: studentID
248 109
249 $envir{sectionName} = $user->section; 110 $envir{sectionName} = $user->section;
250 $envir{sectionNumber} = $envir{sectionName}; 111 $envir{sectionNumber} = $envir{sectionName};
251 $envir{recitationName} = $user->recitation; 112 $envir{recitationName} = $user->recitation;
252 $envir{recitationNumber} = $envir{recitationName}; 113 $envir{recitationNumber} = $envir{recitationName};
253 $envir{setNumber} = $set->id; 114 $envir{setNumber} = $set->set_id;
254 $envir{studentLogin} = $user->id; 115 $envir{studentLogin} = $user->user_id;
255 $envir{studentName} = $user->first_name . " " . $user->last_name; 116 $envir{studentName} = $user->first_name . " " . $user->last_name;
256 $envir{studentID} = $user->student_id; 117 $envir{studentID} = $user->student_id;
257 118
258 # Answer Information 119 # Answer Information
259 # REMOVED: refSubmittedAnswers 120 # REMOVED: refSubmittedAnswers
260 121
261 $envir{inputs_ref} = $formFields; 122 $envir{inputs_ref} = $formFields;
262 123
263 # External Programs 124 # External Programs
125 # ADDED: externalLaTeXPath, externalDvipngPath,
126 # externalGif2EpsPath, externalPng2EpsPath
264 127
265 $envir{externalTTHPath} = $courseEnv->{externalPrograms}->{tth}; 128 $envir{externalTTHPath} = $ce->{externalPrograms}->{tth};
129 $envir{externalLaTeXPath} = $ce->{externalPrograms}->{latex};
266 $envir{externalMath2imgPath} = $courseEnv->{externalPrograms}->{math2img}; 130 $envir{externalDvipngPath} = $ce->{externalPrograms}->{dvipng};
267 131 $envir{externalGif2EpsPath} = $ce->{externalPrograms}->{gif2eps};
132 $envir{externalPng2EpsPath} = $ce->{externalPrograms}->{png2eps};
133 $envir{externalGif2PngPath} = $ce->{externalPrograms}->{gif2png};
134 $envir{externalCheckUrl} = $ce->{externalPrograms}->{checkurl};
268 # Directories and URLs 135 # Directories and URLs
269 # REMOVED: courseName 136 # REMOVED: courseName
137 # ADDED: dvipngTempDir
138 # ADDED: jsMathURL
139 # ADDED: asciimathURL
140 # ADDED: macrosPath
141 # REMOVED: macrosDirectory, courseScriptsDirectory
270 142
271 $envir{cgiDirectory} = undef; 143 $envir{cgiDirectory} = undef;
272 $envir{cgiURL} = undef; 144 $envir{cgiURL} = undef;
273 $envir{classDirectory} = undef; 145 $envir{classDirectory} = undef;
274 $envir{courseScriptsDirectory} = $courseEnv->{webworkDirs}->{macros}."/"; 146 $envir{macrosPath} = $ce->{pg}->{directories}{macrosPath};
147 $envir{appletPath} = $ce->{pg}->{directories}{appletPath};
148 $envir{pgDirectories} = $ce->{pg}->{directories};
275 $envir{htmlDirectory} = $courseEnv->{courseDirs}->{html}."/"; 149 $envir{htmlDirectory} = $ce->{courseDirs}->{html}."/";
276 $envir{htmlURL} = $courseEnv->{courseURLs}->{html}; 150 $envir{htmlURL} = $ce->{courseURLs}->{html}."/";
277 $envir{macroDirectory} = $courseEnv->{courseDirs}->{macros}."/";
278 $envir{templateDirectory} = $courseEnv->{courseDirs}->{templates}."/"; 151 $envir{templateDirectory} = $ce->{courseDirs}->{templates}."/";
279 $envir{tempDirectory} = $courseEnv->{courseDirs}->{html_temp}."/"; 152 $envir{tempDirectory} = $ce->{courseDirs}->{html_temp}."/";
280 $envir{tempURL} = $courseEnv->{courseURLs}->{html_temp}; 153 $envir{tempURL} = $ce->{courseURLs}->{html_temp}."/";
281 $envir{scriptDirectory} = undef; 154 $envir{scriptDirectory} = undef;
282 $envir{webworkDocsURL} = $courseEnv->{webworkURLs}->{docs}; 155 $envir{webworkDocsURL} = $ce->{webworkURLs}->{docs}."/";
156 $envir{localHelpURL} = $ce->{webworkURLs}->{local_help}."/";
157 $envir{jsMathURL} = $ce->{webworkURLs}->{jsMath};
158 $envir{asciimathURL} = $ce->{webworkURLs}->{asciimath};
159 $envir{server_root_url} = $ce->{apache_root_url};
160
161 # Information for sending mail
162
163 $envir{mailSmtpServer} = $ce->{mail}->{smtpServer};
164 $envir{mailSmtpSender} = $ce->{mail}->{smtpSender};
165 $envir{ALLOW_MAIL_TO} = $ce->{mail}->{allowedRecipients};
283 166
284 # Default values for evaluating answers 167 # Default values for evaluating answers
285 168
286 my $ansEvalDefaults = $courseEnv->{pg}->{ansEvalDefaults}; 169 my $ansEvalDefaults = $ce->{pg}->{ansEvalDefaults};
287 $envir{$_} = $ansEvalDefaults->{$_} foreach (keys %$ansEvalDefaults); 170 $envir{$_} = $ansEvalDefaults->{$_} foreach (keys %$ansEvalDefaults);
288 171
172 # ----------------------------------------------------------------------
173
174 my $basename = "equation-$envir{psvn}.$envir{probNum}";
175 $basename .= ".$envir{problemSeed}" if $envir{problemSeed};
176
177 # to make grabbing these options easier, we'll pull them out now...
178 my %imagesModeOptions = %{$ce->{pg}->{displayModeOptions}->{images}};
179
180 # Object for generating equation images
181 $envir{imagegen} = WeBWorK::PG::ImageGenerator->new(
182 tempDir => $ce->{webworkDirs}->{tmp}, # global temp dir
183 latex => $envir{externalLaTeXPath},
184 dvipng => $envir{externalDvipngPath},
185 useCache => 1,
186 cacheDir => $ce->{webworkDirs}->{equationCache},
187 cacheURL => $ce->{webworkURLs}->{equationCache},
188 cacheDB => $ce->{webworkFiles}->{equationCacheDB},
189 useMarkers => ($imagesModeOptions{dvipng_align} && $imagesModeOptions{dvipng_align} eq 'mysql'),
190 dvipng_align => $imagesModeOptions{dvipng_align},
191 dvipng_depth_db => $imagesModeOptions{dvipng_depth_db},
192 );
193
194 # ADDED: jsMath options
195 $envir{jsMath} = {%{$ce->{pg}{displayModeOptions}{jsMath}}};
196
289 # Other things... 197 # Other things...
290 198 $envir{QUIZ_PREFIX} = $options->{QUIZ_PREFIX}; # used by quizzes
291 $envir{PROBLEM_GRADER_TO_USE} = $courseEnv->{pg}->{options}->{grader}; 199 $envir{PROBLEM_GRADER_TO_USE} = $ce->{pg}->{options}->{grader};
200 $envir{PRINT_FILE_NAMES_FOR} = $ce->{pg}->{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR};
201
202 # ADDED: __files__
203 # an array for mapping (eval nnn) to filenames in error messages
204 $envir{__files__} = {
205 root => $ce->{webworkDirs}{root}, # used to shorten filenames
206 pg => $ce->{pg}{directories}{root}, # ditto
207 tmpl => $ce->{courseDirs}{templates}, # ditto
208 };
209
210 # variables for interpreting capa problems and other things to be
211 # seen in a pg file
212 my $specialPGEnvironmentVarHash = $ce->{pg}->{specialPGEnvironmentVars};
213 for my $SPGEV (keys %{$specialPGEnvironmentVarHash}) {
214 $envir{$SPGEV} = $specialPGEnvironmentVarHash->{$SPGEV};
215 }
292 216
293 return \%envir; 217 return \%envir;
294} 218}
295 219
296sub translateDisplayModeNames($) { 220sub translateDisplayModeNames($) {
297 my $name = shift; 221 my $name = shift;
298 return { 222 return DISPLAY_MODES()->{$name};
299 tex => "TeX",
300 plainText => "HTML",
301 formattedText => "HTML_tth",
302 images => "HTML_img"
303 }->{$name};
304} 223}
305 224
306sub safetyFilter { 225sub oldSafetyFilter {
307 my $answer = shift; # accepts one answer and checks it 226 my $answer = shift; # accepts one answer and checks it
308 my $submittedAnswer = $answer; 227 my $submittedAnswer = $answer;
309 $answer = '' unless defined $answer; 228 $answer = '' unless defined $answer;
310 my ($errorno); 229 my ($errorno);
311 $answer =~ tr/\000-\037/ /; 230 $answer =~ tr/\000-\037/ /;
315 $errorno = 0; ## don't report blank answer as error 234 $errorno = 0; ## don't report blank answer as error
316 return ($answer,$errorno); 235 return ($answer,$errorno);
317 } 236 }
318 # replace ^ with ** (for exponentiation) 237 # replace ^ with ** (for exponentiation)
319 # $answer =~ s/\^/**/g; 238 # $answer =~ s/\^/**/g;
320 # Return if forbidden characters are found 239 # Return if forbidden characters are found
321 unless ($answer =~ /^[a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)]+$/ ) { 240 unless ($answer =~ /^[a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\[\]\(\)\,\|]+$/ ) {
322 $answer =~ tr/a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)/#/c; 241 $answer =~ tr/a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)/#/c;
323 $errorno = "<BR>There are forbidden characters in your answer: $submittedAnswer<BR>"; 242 $errorno = "<BR>There are forbidden characters in your answer: $submittedAnswer<BR>";
324 return ($answer,$errorno); 243 return ($answer,$errorno);
325 } 244 }
326 $errorno = 0; 245 $errorno = 0;
327 return($answer, $errorno); 246 return($answer, $errorno);
328} 247}
329 248
249sub nullSafetyFilter {
250 return shift, 0; # no errors
251}
252
3301; 2531;
331 254
332__END__ 255__END__
333 256
334=head1 SYNOPSIS 257=head1 SYNOPSIS
335 258
336 $pg = WeBWorK::PG->new( 259 $pg = WeBWorK::PG->new(
337 $courseEnv, # a WeBWorK::CourseEnvironment object 260 $ce, # a WeBWorK::CourseEnvironment object
338 $userName, 261 $user, # a WeBWorK::DB::Record::User object
339 $sessionKey, 262 $sessionKey,
340 $setName, 263 $set, # a WeBWorK::DB::Record::UserSet object
341 $problemNumber, 264 $problem, # a WeBWorK::DB::Record::UserProblem object
265 $psvn,
266 $formFields # in &WeBWorK::Form::Vars format
342 { # translation options 267 { # translation options
343 displayMode => "images", # (plainText|formattedText|images) 268 displayMode => "images", # (plainText|formattedText|images)
344 showHints => 1, # (0|1) 269 showHints => 1, # (0|1)
345 showSolutions => 0, # (0|1) 270 showSolutions => 0, # (0|1)
346 refreshMath2img => 0, # (0|1) 271 refreshMath2img => 0, # (0|1)
347 processAnswers => 1, # (0|1) 272 processAnswers => 1, # (0|1)
348 }, 273 },
349 $formFields # in WeBWorK::Form::Vars format
350 ); 274 );
351 275
352 $translator = $pg->{translator}; # WeBWorK::PG::Translator 276 $translator = $pg->{translator}; # WeBWorK::PG::Translator
353 $body = $pg->{body_text}; # text string 277 $body = $pg->{body_text}; # text string
354 $header = $pg->{head_text}; # text string 278 $header = $pg->{head_text}; # text string
359 $warnings = $pg->{warnings}; # text string 283 $warnings = $pg->{warnings}; # text string
360 $flags = $pg->{flags}; # hash reference 284 $flags = $pg->{flags}; # hash reference
361 285
362=head1 DESCRIPTION 286=head1 DESCRIPTION
363 287
364WeBWorK::PG encapsulates the PG translation process, making multiple calls to 288WeBWorK::PG is a factory for modules which use the WeBWorK::PG API. Notable
365WeBWorK::PG::Translator. Much of the flexibility of the Translator is hidden, 289modules which use this API (and exist) are WeBWorK::PG::Local and
366instead making choices that are appropriate for the webwork-modperl system. 290WeBWorK::PG::Remote. The course environment key $pg{renderer} is consulted to
291determine which render to use.
367 292
368=head1 CONSTRUCTION 293=head1 THE WEBWORK::PG API
294
295Modules which support this API must implement the following method:
369 296
370=over 297=over
371 298
372=item new (ENVIRONMENT, USER, KEY, SET, PROBLEM, OPTIONS, FIELDS) 299=item new ENVIRONMENT, USER, KEY, SET, PROBLEM, PSVN, FIELDS, OPTIONS
373 300
374The C<new> method creates a translator, initializes it using the parameters 301The C<new> method creates a translator, initializes it using the parameters
375specified, translates a PG file, and processes answers. It returns a reference 302specified, translates a PG file, and processes answers. It returns a reference
376to a blessed hash containing the results of the translation process. 303to a blessed hash containing the results of the translation process.
377 304
385 312
386a WeBWorK::CourseEnvironment object 313a WeBWorK::CourseEnvironment object
387 314
388=item USER 315=item USER
389 316
390the name of the user for whom to render 317a WeBWorK::User object
391 318
392=item KEY 319=item KEY
393 320
394the session key of the current session 321the session key of the current session
395 322
396=item SET 323=item SET
397 324
398the name of the problem set from which to get the problem 325a WeBWorK::Set object
399 326
400=item PROBLEM 327=item PROBLEM
401 328
402the number of the problem to render 329a WeBWorK::DB::Record::UserProblem object. The contents of the source_file
330field can specify a PG file either by absolute path or path relative to the
331"templates" directory. I<The caller should remove taint from this value before
332passing!>
403 333
404=item OPTIONS 334=item PSVN
405 335
406a reference to a hash containing the following data: 336the problem set version number
407
408=over
409
410=item displayMode
411
412one of "plainText", "formattedText", or "images"
413
414=item showHints
415
416boolean, render hints
417
418=item showSolutions
419
420boolean, render solutions
421
422=item refreshMath2img
423
424boolean, force images created by math2img (in "images" mode) to be recreated,
425even if the PG source has not been updated.
426
427=item processAnswers
428
429boolean, call answer evaluators and graders
430
431=back
432 337
433=item FIELDS 338=item FIELDS
434 339
435a reference to a hash (as returned by &WeBWorK::Form::Vars) containing form 340a reference to a hash (as returned by &WeBWorK::Form::Vars) containing form
436fields submitted by a problem processor. The translator will look for fields 341fields submitted by a problem processor. The translator will look for fields
437like "AnSwEr[0-9]" containing submitted student answers. 342like "AnSwEr[0-9]" containing submitted student answers.
438 343
344=item OPTIONS
345
346a reference to a hash containing the following data:
347
348=over
349
350=item displayMode
351
352one of "plainText", "formattedText", or "images"
353
354=item showHints
355
356boolean, render hints
357
358=item showSolutions
359
360boolean, render solutions
361
362=item refreshMath2img
363
364boolean, force images created by math2img (in "images" mode) to be recreated,
365even if the PG source has not been updated. FIXME: remove this option.
366
367=item processAnswers
368
369boolean, call answer evaluators and graders
370
371=back
372
439=back 373=back
440 374
441=head2 RETURN VALUE 375=head2 RETURN VALUE
442 376
443The C<new> method returns a blessed hash reference containing the following 377The C<new> method returns a blessed hash reference containing the following
484 418
485A hash containing PG_flags (see the Translator docs). 419A hash containing PG_flags (see the Translator docs).
486 420
487=back 421=back
488 422
489=head1 OPERATION 423=head1 METHODS PROVIDED BY THE BASE CLASS
490 424
491WeBWorK::PG goes through the following operations when constructed: 425The following methods are provided for use by subclasses of WeBWorK::PG.
492 426
493=over 427=over
494 428
495=item Get database information 429=item defineProblemEnvir ENVIRONMENT, USER, KEY, SET, PROBLEM, PSVN, FIELDS, OPTIONS
496 430
497Retrieve information about the current user, set, and problem from the 431Generate a problem environment hash to pass to the renderer.
498database.
499 432
500=item Create a translator 433=item translateDisplayModeNames NAME
501 434
502Instantiate a WeBWorK::PG::Translator object. 435NAME contains
503
504=item Set the directory hash
505
506Set the translator's directory hash (courseScripts, macros, templates, and temp
507directories) from the course environment.
508
509=item Evaluate PG modules
510
511Using the module list from the course environment (pg->modules), perform a
512"use"-like operation to evaluate modules at runtime.
513
514=item Set the problem environment
515
516Use data from the user, set, and problem, as well as the course environemnt and
517translation options, to set the problem environment.
518
519=item Initialize the translator
520
521Call &WeBWorK::PG::Translator::initialize. What more do you want?
522
523=item Load PG.pl and dangerousMacros.pl
524
525These macros must be loaded without opcode masking, so they are loaded here.
526
527=item Set the opcode mask
528
529Set the opcode mask to the default specified by WeBWorK::PG::Translator.
530
531=item Load the problem source
532
533Give the problem source to the translator.
534
535=item Install a safety filter
536
537The safety filter is used to preprocess student input before evaluation. The
538default safety filter, &WeBWorK::PG::safetyFilter, is used.
539
540=item Translate the problem source
541
542Call &WeBWorK::PG::Translator::translate to render the problem source into the
543format given by the display mode.
544
545=item Process student answers
546
547Use form field inputs to evaluate student answers.
548
549=item Load the problem state
550
551Use values from the database to initialize the problem state, so that the
552grader will have a point of reference.
553
554=item Determine an entry order
555
556Use the ANSWER_ENTRY_ORDER flag to determine the order of answers in the
557problem. This is important for problems with dependancies among parts.
558
559=item Install a grader
560
561Use the PROBLEM_GRADER_TO_USE flag, or a default from the course environment,
562to install a grader.
563
564=item Grade the problem
565
566Use the selected grader to grade the problem.
567 436
568=back 437=back
569 438
570=head1 AUTHOR 439=head1 AUTHOR
571 440

Legend:
Removed from v.492  
changed lines
  Added in v.4376

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9