[system] / trunk / webwork2 / lib / WeBWorK / PG.pm Repository:
ViewVC logotype

Diff of /trunk/webwork2/lib/WeBWorK/PG.pm

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

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

Legend:
Removed from v.476  
changed lines
  Added in v.4091

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9