[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 455 Revision 818
1################################################################################ 1################################################################################
2# WeBWorK mod_perl (c) 1995-2002 WeBWorK Team, Univeristy of Rochester 2# WeBWorK mod_perl (c) 2000-2002 WeBWorK Project
3# $Id$ 3# $Id$
4################################################################################ 4################################################################################
5 5
6package WeBWorK::PG; 6package WeBWorK::PG;
7 7
8=head1 NAME 8=head1 NAME
9 9
10WeBWorK::PG - Wrap the action of the PG Translator in an easy-to-use API 10WeBWorK::PG - Wrap the action of the PG Translator in an easy-to-use API.
11 11
12=cut 12=cut
13 13
14use strict; 14use strict;
15use warnings; 15use warnings;
16use WeBWorK::DB::Classlist; 16use File::Path qw(rmtree);
17use WeBWorK::DB::WW; 17use File::Temp qw(tempdir);
18use WeBWorK::PG::Translator; 18use WeBWorK::PG::Translator;
19use WeBWorK::Utils qw(readFile formatDateTime); 19use WeBWorK::Utils qw(readFile formatDateTime writeTimingLogEntry);
20 20
21sub new($$$$$$$$) { 21sub new($$$$$$$$) {
22 my $invocant = shift; 22 my $invocant = shift;
23 my $class = ref($invocant) || $invocant; 23 my $class = ref($invocant) || $invocant;
24 my ( 24 my (
25 $courseEnv, 25 $courseEnv,
26 $userName, 26 $user,
27 $key, 27 $key,
28 $setName, 28 $set,
29 $problemNumber, 29 $problem,
30 $psvn,
31 $formFields, # in CGI::Vars format
30 $translationOptions, # hashref containing options for the 32 $translationOptions, # hashref containing options for the
31 # translator, such as whether to show 33 # translator, such as whether to show
32 # hints and the display mode to use 34 # hints and the display mode to use
33 $formFields, # in CGI::Vars format
34 ) = @_; 35 ) = @_;
35 36
36 # get database information 37 # write timing log entry
37 my $classlist = WeBWorK::DB::Classlist->new($courseEnv); 38 writeTimingLogEntry($courseEnv, "WeBWorK::PG::new",
38 my $wwdb = WeBWorK::DB::WW->new($courseEnv); 39 "user=".$user->id.",problem=".$courseEnv->{courseName}."/".$set->set_id."/".$problem->problem_id.",mode=".$translationOptions->{displayMode},
39 my $user = $classlist->getUser($userName); 40 "begin");
40 my $set = $wwdb->getSet($userName, $setName); 41
41 my $problem = $wwdb->getProblem($userName, $setName, $problemNumber); 42 # install a local warn handler to collect warnings
42 my $psvn = $wwdb->getPSVN($userName, $setName); 43 my $warnings = "";
44 local $SIG{__WARN__} = sub { $warnings .= shift }
45 if $courseEnv->{pg}->{options}->{catchWarnings};
43 46
44 # create a Translator 47 # create a Translator
45 warn "PG: creating a Translator\n"; 48 #warn "PG: creating a Translator\n";
46 my $translator = WeBWorK::PG::Translator->new; 49 my $translator = WeBWorK::PG::Translator->new;
47 50
48 # set the directory hash 51 # set the directory hash
49 warn "PG: setting the directory hash\n"; 52 #warn "PG: setting the directory hash\n";
50 $translator->rh_directories({ 53 $translator->rh_directories({
51 courseScriptsDirectory => $courseEnv->{webworkDirs}->{macros}, 54 courseScriptsDirectory => $courseEnv->{webworkDirs}->{macros},
52 macroDirectory => $courseEnv->{courseDirs}->{macros}, 55 macroDirectory => $courseEnv->{courseDirs}->{macros},
53 templateDirectory => $courseEnv->{courseDirs}->{templates}, 56 templateDirectory => $courseEnv->{courseDirs}->{templates},
54 tempDirectory => $courseEnv->{courseDirs}->{html_temp}, 57 tempDirectory => $courseEnv->{courseDirs}->{html_temp},
55 }); 58 });
56 59
57 # evaluate modules and "extra packages" 60 # evaluate modules and "extra packages"
58 warn "PG: evaluating modules and \"extra packages\"\n"; 61 #warn "PG: evaluating modules and \"extra packages\"\n";
59 my @modules = @{ $courseEnv->{pg}->{modules} }; 62 my @modules = @{ $courseEnv->{pg}->{modules} };
60 foreach my $module_packages (@modules) { 63 foreach my $module_packages_ref (@modules) {
61 # the first item in $module_packages is the main package 64 my ($module, @extra_packages) = @$module_packages_ref;
65 # the first item is the main package
62 $translator->evaluate_modules(shift @$module_packages); 66 $translator->evaluate_modules($module);
63 # the remaining items are "extra" packages 67 # the remaining items are "extra" packages
64 $translator->load_extra_packages(@$module_packages); 68 $translator->load_extra_packages(@extra_packages);
65 } 69 }
66 70
67 # set the environment (from defineProblemEnvir) 71 # set the environment (from defineProblemEnvir)
68 warn "PG: setting the environment (from defineProblemEnvir)\n"; 72 #warn "PG: setting the environment (from defineProblemEnvir)\n";
73 my $envir = defineProblemEnvir(
74 $courseEnv,
75 $user,
76 $key,
77 $set,
78 $problem,
79 $psvn,
80 $formFields,
81 $translationOptions,
82 );
69 $translator->environment(defineProblemEnvir( 83 $translator->environment($envir);
70 $courseEnv, $user, $key, $set, $problem, $psvn, $formFields, $translationOptions));
71 84
72 # initialize the Translator 85 # initialize the Translator
73 warn "PG: initializing the Translator\n"; 86 #warn "PG: initializing the Translator\n";
74 $translator->initialize(); 87 $translator->initialize();
75 88
76 # load PG.pl and dangerousMacros.pl using unrestricted_load 89 # load IO.pl, PG.pl, and dangerousMacros.pl using unrestricted_load
77 # i'd like to change this at some point to have the same sort of interface to global.conf 90 # i'd like to change this at some point to have the same sort of interface to global.conf
78 # that the module loading does -- have a list of macros to load unrestrictedly. 91 # that the module loading does -- have a list of macros to load unrestrictedly.
79 warn "PG: loading PG.pl and dangerousMacros.pl using unrestricted_load\n"; 92 #warn "PG: loading IO.pl, PG.pl, and dangerousMacros.pl using unrestricted_load\n";
93 foreach (qw(IO.pl PG.pl dangerousMacros.pl)) {
80 my $pg_pl = $courseEnv->{webworkDirs}->{macros} . "/PG.pl"; 94 my $macroPath = $courseEnv->{webworkDirs}->{macros} . "/$_";
81 my $dangerousMacros_pl = $courseEnv->{webworkDirs}->{macros} . "/dangerousMacros.pl";
82 my $err = $translator->unrestricted_load($pg_pl); 95 my $err = $translator->unrestricted_load($macroPath);
83 warn "Error while loading $pg_pl: $err" if $err; 96 warn "Error while loading $macroPath: $err" if $err;
84 $err = $translator->unrestricted_load($dangerousMacros_pl); 97 }
85 warn "Error while loading $dangerousMacros_pl: $err" if $err;
86 98
87 # set the opcode mask (using default values) 99 # set the opcode mask (using default values)
88 warn "PG: setting the opcode mask (using default values)\n"; 100 #warn "PG: setting the opcode mask (using default values)\n";
89 $translator->set_mask(); 101 $translator->set_mask();
90 102
91 # store the problem source 103 # store the problem source
92 warn "PG: storing the problem source\n"; 104 #warn "PG: storing the problem source\n";
105 my $sourceFile = $problem->source_file;
93 my $sourceFile = $courseEnv->{courseDirs}->{templates}."/".$problem->source_file; 106 $sourceFile = $courseEnv->{courseDirs}->{templates}."/".$sourceFile
107 unless ($sourceFile =~ /^\//);
94 $translator->source_string(readFile($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 }
95 126
96 # install a safety filter (&safetyFilter) 127 # install a safety filter (&safetyFilter)
97 warn "PG: installing a safety filter\n"; 128 #warn "PG: installing a safety filter\n";
98 $translator->rf_safety_filter(\&safetyFilter); 129 $translator->rf_safety_filter(\&safetyFilter);
99 130
131 # write timing log entry -- the translator is now all set up
132 writeTimingLogEntry($courseEnv, "WeBWorK::PG::new",
133 "initialized",
134 "intermediate");
135
100 # translate the PG source into text 136 # translate the PG source into text
101 warn "PG: translating the PG source into text\n"; 137 #warn "PG: translating the PG source into text\n";
102 $translator->translate(); 138 $translator->translate();
103 139
104 # [in Problem.pm and processProblem8.pl, "install a grader" is here] 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 }
105 146
147 my ($result, $state); # we'll need these on the other side of the if block!
148 if ($translationOptions->{processAnswers}) {
149
106 # process student answers 150 # process student answers
107 warn "PG: processing student answers\n"; 151 #warn "PG: processing student answers\n";
108 $translator->process_answers($formFields); 152 $translator->process_answers($formFields);
109 153
110 # retrieve the problem state and give it to the translator 154 # retrieve the problem state and give it to the translator
111 warn "PG: retrieving the problem state and giving it to the translator\n"; 155 #warn "PG: retrieving the problem state and giving it to the translator\n";
112 $translator->rh_problem_state({ 156 $translator->rh_problem_state({
113 recorded_score => $problem->status, 157 recorded_score => $problem->status,
114 num_of_correct_ans => $problem->num_correct, 158 num_of_correct_ans => $problem->num_correct,
115 num_of_incorrect_ans => $problem->num_incorrect, 159 num_of_incorrect_ans => $problem->num_incorrect,
116 }); 160 });
117 161
118 # determine an entry order -- the ANSWER_ENTRY_ORDER flag is built by 162 # determine an entry order -- the ANSWER_ENTRY_ORDER flag is built by
119 # the PG macro package (PG.pl) 163 # the PG macro package (PG.pl)
120 warn "PG: determining an entry order\n"; 164 #warn "PG: determining an entry order\n";
121 my @answerOrder = 165 my @answerOrder =
122 $translator->rh_flags->{ANSWER_ENTRY_ORDER} 166 $translator->rh_flags->{ANSWER_ENTRY_ORDER}
123 ? @{ $translator->rh_flags->{ANSWER_ENTRY_ORDER} } 167 ? @{ $translator->rh_flags->{ANSWER_ENTRY_ORDER} }
124 : keys %{ $translator->rh_evaluated_answers }; 168 : keys %{ $translator->rh_evaluated_answers };
125 169
126 # install a grader -- use the one specified in the problem, 170 # install a grader -- use the one specified in the problem,
127 # or fall back on the default from the course environment. 171 # or fall back on the default from the course environment.
128 # (two magic strings are accepted, to avoid having to 172 # (two magic strings are accepted, to avoid having to
129 # reference code when it would be difficult.) 173 # reference code when it would be difficult.)
130 warn "PG: installing a grader\n"; 174 #warn "PG: installing a grader\n";
131 my $grader = $translator->rh_flags->{PROBLEM_GRADER_TO_USE} 175 my $grader = $translator->rh_flags->{PROBLEM_GRADER_TO_USE}
132 || $courseEnv->{pg}->{options}->{grader}; 176 || $courseEnv->{pg}->{options}->{grader};
133 $grader = $translator->rf_std_problem_grader 177 $grader = $translator->rf_std_problem_grader
134 if $grader eq "std_problem_grader"; 178 if $grader eq "std_problem_grader";
135 $grader = $translator->rf_avg_problem_grader 179 $grader = $translator->rf_avg_problem_grader
136 if $grader eq "avg_problem_grader"; 180 if $grader eq "avg_problem_grader";
137 die "Problem grader $grader is not a CODE reference." 181 die "Problem grader $grader is not a CODE reference."
138 unless ref $grader eq "CODE"; 182 unless ref $grader eq "CODE";
139 $translator->rf_problem_grader($grader); 183 $translator->rf_problem_grader($grader);
140 184
141 # grade the problem 185 # grade the problem
142 warn "PG: grading the problem\n"; 186 #warn "PG: grading the problem\n";
143 my ($result, $state) = $translator->grade_problem( 187 ($result, $state) = $translator->grade_problem(
144 answers_submitted => $translationOptions->{processAnswers}, 188 answers_submitted => $translationOptions->{processAnswers},
145 ANSWER_ENTRY_ORDER => \@answerOrder, 189 ANSWER_ENTRY_ORDER => \@answerOrder,
146 ); 190 );
191
192 }
193
194 # write timing log entry
195 writeTimingLogEntry($courseEnv, "WeBWorK::PG::new", "", "end");
147 196
148 # return an object which contains the translator and the results of 197 # return an object which contains the translator and the results of
149 # the translation process. this is DIFFERENT from the "format expected 198 # the translation process. this is DIFFERENT from the "format expected
150 # by Webwork.pm (and I believe processProblem8, but check.)" 199 # by Webwork.pm (and I believe processProblem8, but check.)"
151 return bless { 200 return bless {
153 head_text => ${ $translator->r_header }, 202 head_text => ${ $translator->r_header },
154 body_text => ${ $translator->r_text }, 203 body_text => ${ $translator->r_text },
155 answers => $translator->rh_evaluated_answers, 204 answers => $translator->rh_evaluated_answers,
156 result => $result, 205 result => $result,
157 state => $state, 206 state => $state,
158 errors => $translator->errors, # *** what is this doing? 207 errors => $translator->errors,
159 warnings => undef, # *** gotta catch warnings eventually... 208 warnings => $warnings,
160 flags => $translator->rh_flags, 209 flags => $translator->rh_flags,
161 }, $class; 210 }, $class;
162} 211}
163 212
164# ----- 213# -----
180 # PG environment variables 229 # PG environment variables
181 # from docs/pglanguage/pgreference/environmentvariables as of 06/25/2002 230 # from docs/pglanguage/pgreference/environmentvariables as of 06/25/2002
182 # any changes are noted by "ADDED:" or "REMOVED:" 231 # any changes are noted by "ADDED:" or "REMOVED:"
183 232
184 # Vital state information 233 # Vital state information
185 # ADDED: displayHintsQ, displaySolutionsQ 234 # ADDED: displayHintsQ, displaySolutionsQ, refreshMath2img,
235 # texDisposition
186 236
187 $envir{psvn} = $psvn; 237 $envir{psvn} = $psvn;
188 $envir{psvnNumber} = $envir{psvn}; 238 $envir{psvnNumber} = $envir{psvn};
189 $envir{probNum} = $problem->id; 239 $envir{probNum} = $problem->problem_id;
190 $envir{questionNumber} = $envir{probNum}; 240 $envir{questionNumber} = $envir{probNum};
191 $envir{fileName} = $problem->source_file; 241 $envir{fileName} = $problem->source_file;
192 $envir{probFileName} = $envir{fileName}; 242 $envir{probFileName} = $envir{fileName};
193 $envir{problemSeed} = $problem->problem_seed; 243 $envir{problemSeed} = $problem->problem_seed;
194 $envir{displayMode} = translateDisplayModeNames($options->{displayMode}); 244 $envir{displayMode} = translateDisplayModeNames($options->{displayMode});
195 $envir{languageMode} = $envir{displayMode}; 245 $envir{languageMode} = $envir{displayMode};
196 $envir{outputMode} = $envir{displayMode}; 246 $envir{outputMode} = $envir{displayMode};
197 $envir{displayHintsQ} = $options->{hints}; 247 $envir{displayHintsQ} = $options->{showHints};
198 $envir{displaySolutionsQ} = $options->{solutions}; 248 $envir{displaySolutionsQ} = $options->{showSolutions};
199 $envir{refreshMath2img} = $options->{refreshMath2img}; 249 $envir{refreshMath2img} = $options->{refreshMath2img};
250 $envir{texDisposition} = "pdf"; # in webwork-modperl, we use pdflatex
200 251
201 # Problem Information 252 # Problem Information
202 # ADDED: courseName 253 # ADDED: courseName, formatedDueDate
203 254
204 $envir{openDate} = $set->open_date; 255 $envir{openDate} = $set->open_date;
205 $envir{formattedOpenDate} = formatDateTime($envir{openDate}); 256 $envir{formattedOpenDate} = formatDateTime($envir{openDate});
206 $envir{dueDate} = $set->due_date; 257 $envir{dueDate} = $set->due_date;
207 $envir{formattedDueDate} = formatDateTime($envir{dueDate}); 258 $envir{formattedDueDate} = formatDateTime($envir{dueDate});
259 $envir{formatedDueDate} = $envir{formattedDueDate}; # typo in many header files
208 $envir{answerDate} = $set->answer_date; 260 $envir{answerDate} = $set->answer_date;
209 $envir{formattedAnswerDate} = formatDateTime($envir{answerDate}); 261 $envir{formattedAnswerDate} = formatDateTime($envir{answerDate});
210 $envir{numOfAttempts} = $problem->num_correct + $problem->num_incorrect; 262 $envir{numOfAttempts} = ($problem->num_correct || 0) + ($problem->num_incorrect || 0);
211 $envir{problemValue} = $problem->value; 263 $envir{problemValue} = $problem->value;
212 $envir{sessionKey} = $key; 264 $envir{sessionKey} = $key;
213 $envir{courseName} = $courseEnv->{courseName}; 265 $envir{courseName} = $courseEnv->{courseName};
214 266
215 # Student Information 267 # Student Information
217 269
218 $envir{sectionName} = $user->section; 270 $envir{sectionName} = $user->section;
219 $envir{sectionNumber} = $envir{sectionName}; 271 $envir{sectionNumber} = $envir{sectionName};
220 $envir{recitationName} = $user->recitation; 272 $envir{recitationName} = $user->recitation;
221 $envir{recitationNumber} = $envir{recitationName}; 273 $envir{recitationNumber} = $envir{recitationName};
222 $envir{setNumber} = $set->id; 274 $envir{setNumber} = $set->set_id;
223 $envir{studentLogin} = $user->id; 275 $envir{studentLogin} = $user->id;
224 $envir{studentName} = $user->first_name . " " . $user->last_name; 276 $envir{studentName} = $user->first_name . " " . $user->last_name;
225 $envir{studentID} = $user->student_id; 277 $envir{studentID} = $user->student_id;
226 278
227 # Answer Information 279 # Answer Information
228 # REMOVED: refSubmittedAnswers 280 # REMOVED: refSubmittedAnswers
229 281
230 $envir{inputs_ref} = $formFields; 282 $envir{inputs_ref} = $formFields;
231 283
232 # External Programs 284 # External Programs
285 # ADDED: externalLaTeXPath, externalDvipngPath,
286 # externalGif2EpsPath, externalPng2EpsPath
233 287
234 $envir{externalTTHPath} = $courseEnv->{externalPrograms}->{tth}; 288 $envir{externalTTHPath} = $courseEnv->{externalPrograms}->{tth};
289 $envir{externalLaTeXPath} = $courseEnv->{externalPrograms}->{latex};
235 $envir{externalMath2imgPath} = $courseEnv->{externalPrograms}->{math2img}; 290 $envir{externalDvipngPath} = $courseEnv->{externalPrograms}->{dvipng};
291 $envir{externalGif2EpsPath} = $courseEnv->{externalPrograms}->{gif2eps};
292 $envir{externalPng2EpsPath} = $courseEnv->{externalPrograms}->{png2eps};
293 $envir{externalGif2PngPath} = $courseEnv->{externalPrograms}->{gif2png};
236 294
237 # Directories and URLs 295 # Directories and URLs
238 # REMOVED: courseName 296 # REMOVED: courseName
297 # ADDED: dvipngTempDir
239 298
240 $envir{cgiDirectory} = undef; 299 $envir{cgiDirectory} = undef;
241 $envir{cgiURL} = undef; 300 $envir{cgiURL} = undef;
242 $envir{classDirectory} = undef; 301 $envir{classDirectory} = undef;
243 $envir{courseScriptsDirectory} = $courseEnv->{webworkDirs}->{macros}."/"; 302 $envir{courseScriptsDirectory} = $courseEnv->{webworkDirs}->{macros}."/";
244 $envir{htmlDirectory} = $courseEnv->{courseDirs}->{html}."/"; 303 $envir{htmlDirectory} = $courseEnv->{courseDirs}->{html}."/";
245 $envir{htmlURL} = $courseEnv->{courseURLs}->{html}; 304 $envir{htmlURL} = $courseEnv->{courseURLs}->{html}."/";
246 $envir{macroDirectory} = $courseEnv->{courseDirs}->{macros}."/"; 305 $envir{macroDirectory} = $courseEnv->{courseDirs}->{macros}."/";
247 $envir{templateDirectory} = $courseEnv->{courseDirs}->{templates}."/"; 306 $envir{templateDirectory} = $courseEnv->{courseDirs}->{templates}."/";
248 $envir{tempDirectory} = $courseEnv->{courseDirs}->{html_temp}."/"; 307 $envir{tempDirectory} = $courseEnv->{courseDirs}->{html_temp}."/";
249 $envir{tempURL} = $courseEnv->{courseURLs}->{html_temp}; 308 $envir{tempURL} = $courseEnv->{courseURLs}->{html_temp}."/";
250 $envir{scriptDirectory} = undef; 309 $envir{scriptDirectory} = undef;
251 $envir{webworkDocsURL} = $courseEnv->{webworkURLs}->{docs}; 310 $envir{webworkDocsURL} = $courseEnv->{webworkURLs}->{docs}."/";
311 $envir{dvipngTempDir} = $options->{displayMode} eq 'images'
312 ? tempdir("webwork-dvipng-XXXXXXXX", DIR => $envir{tempDirectory})
313 : undef;
314
315 # Information for sending mail
316
317 $envir{mailSmtpServer} = $courseEnv->{mail}->{smtpServer};
318 $envir{mailSmtpSender} = $courseEnv->{mail}->{smtpSender};
319 $envir{ALLOW_MAIL_TO} = $courseEnv->{mail}->{allowedRecipients};
252 320
253 # Default values for evaluating answers 321 # Default values for evaluating answers
254 322
255 my $ansEvalDefaults = $courseEnv->{pg}->{ansEvalDefaults}; 323 my $ansEvalDefaults = $courseEnv->{pg}->{ansEvalDefaults};
256 $envir{$_} = $ansEvalDefaults->{$_} foreach (keys %$ansEvalDefaults); 324 $envir{$_} = $ansEvalDefaults->{$_} foreach (keys %$ansEvalDefaults);
263} 331}
264 332
265sub translateDisplayModeNames($) { 333sub translateDisplayModeNames($) {
266 my $name = shift; 334 my $name = shift;
267 return { 335 return {
336 tex => "TeX",
268 plainText => "HTML", 337 plainText => "HTML",
269 formattedText => "HTML_tth", 338 formattedText => "HTML_tth",
270 images => "HTML_img" 339 images => "HTML_img"
271 }->{$name}; 340 }->{$name};
272} 341}
283 $errorno = 0; ## don't report blank answer as error 352 $errorno = 0; ## don't report blank answer as error
284 return ($answer,$errorno); 353 return ($answer,$errorno);
285 } 354 }
286 # replace ^ with ** (for exponentiation) 355 # replace ^ with ** (for exponentiation)
287 # $answer =~ s/\^/**/g; 356 # $answer =~ s/\^/**/g;
288 # Return if forbidden characters are found 357 # Return if forbidden characters are found
289 unless ($answer =~ /^[a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)]+$/ ) { 358 unless ($answer =~ /^[a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)]+$/ ) {
290 $answer =~ tr/a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)/#/c; 359 $answer =~ tr/a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)/#/c;
291 $errorno = "<BR>There are forbidden characters in your answer: $submittedAnswer<BR>"; 360 $errorno = "<BR>There are forbidden characters in your answer: $submittedAnswer<BR>";
292 return ($answer,$errorno); 361 return ($answer,$errorno);
293 } 362 }
300__END__ 369__END__
301 370
302=head1 SYNOPSIS 371=head1 SYNOPSIS
303 372
304 $pg = WeBWorK::PG->new( 373 $pg = WeBWorK::PG->new(
305 $courseEnv, # a WeBWorK::CourseEnvironment object 374 $courseEnv, # a WeBWorK::CourseEnvironment object
306 $userName, 375 $user, # a WeBWorK::DB::Record::User object
307 $sessionKey, 376 $sessionKey,
308 $setName, 377 $set, # a WeBWorK::DB::Record::UserSet object
309 $problemNumber, 378 $problem, # a WeBWorK::DB::Record::UserProblem object
379 $psvn,
380 $formFields # in &WeBWorK::Form::Vars format
310 { # translation options 381 { # translation options
311 displayMode => "images", # (plainText|formattedText|images) 382 displayMode => "images", # (plainText|formattedText|images)
312 showHints => 1, # (0|1) 383 showHints => 1, # (0|1)
313 showSolutions => 0, # (0|1) 384 showSolutions => 0, # (0|1)
314 refreshMath2img => 0, # (0|1) 385 refreshMath2img => 0, # (0|1)
315 processAnswers => 1, # (0|1) 386 processAnswers => 1, # (0|1)
316 }, 387 },
317 $formFields # in WeBWorK::Form::Vars format
318 ); 388 );
319 389
320 $translator = $pg->{translator}; # WeBWorK::PG::Translator 390 $translator = $pg->{translator}; # WeBWorK::PG::Translator
321 $body = $pg->{body_text}; # text string 391 $body = $pg->{body_text}; # text string
322 $header = $pg->{head_text}; # text string 392 $header = $pg->{head_text}; # text string
335 405
336=head1 CONSTRUCTION 406=head1 CONSTRUCTION
337 407
338=over 408=over
339 409
340=item new (ENVIRONMENT, USER, KEY, SET, PROBLEM, OPTIONS, FIELDS) 410=item new (ENVIRONMENT, USER, KEY, SET, PROBLEM, PSVN, FIELDS, OPTIONS)
341 411
342The C<new> method creates a translator, initializes it using the parameters 412The C<new> method creates a translator, initializes it using the parameters
343specified, translates a PG file, and processes answers. It returns a reference 413specified, translates a PG file, and processes answers. It returns a reference
344to a blessed hash containing the results of the translation process. 414to a blessed hash containing the results of the translation process.
345 415
353 423
354a WeBWorK::CourseEnvironment object 424a WeBWorK::CourseEnvironment object
355 425
356=item USER 426=item USER
357 427
358the name of the user for whom to render 428a WeBWorK::User object
359 429
360=item KEY 430=item KEY
361 431
362the session key of the current session 432the session key of the current session
363 433
364=item SET 434=item SET
365 435
366the name of the problem set from which to get the problem 436a WeBWorK::Set object
367 437
368=item PROBLEM 438=item PROBLEM
369 439
370the number of the problem to render 440a WeBWorK::DB::Record::UserProblem object. The contents of the source_file
441field can specify a PG file either by absolute path or path relative to the
442"templates" directory. I<The caller should remove taint from this value before
443passing!>
371 444
372=item OPTIONS 445=item PSVN
373 446
374a reference to a hash containing the following data: 447the problem set version number
375
376=over
377
378=item displayMode
379
380one of "plainText", "formattedText", or "images"
381
382=item showHints
383
384boolean, render hints
385
386=item showSolutions
387
388boolean, render solutions
389
390=item refreshMath2img
391
392boolean, force images created by math2img (in "images" mode) to be recreated,
393even if the PG source has not been updated.
394
395=item processAnswers
396
397boolean, call answer evaluators and graders
398
399=back
400 448
401=item FIELDS 449=item FIELDS
402 450
403a reference to a hash (as returned by &WeBWorK::Form::Vars) containing form 451a reference to a hash (as returned by &WeBWorK::Form::Vars) containing form
404fields submitted by a problem processor. The translator will look for fields 452fields submitted by a problem processor. The translator will look for fields
405like "AnSwEr[0-9]" containing submitted student answers. 453like "AnSwEr[0-9]" containing submitted student answers.
406 454
455=item OPTIONS
456
457a reference to a hash containing the following data:
458
459=over
460
461=item displayMode
462
463one of "plainText", "formattedText", or "images"
464
465=item showHints
466
467boolean, render hints
468
469=item showSolutions
470
471boolean, render solutions
472
473=item refreshMath2img
474
475boolean, force images created by math2img (in "images" mode) to be recreated,
476even if the PG source has not been updated.
477
478=item processAnswers
479
480boolean, call answer evaluators and graders
481
482=back
483
407=back 484=back
408 485
409=head2 RETURN VALUE 486=head2 RETURN VALUE
410 487
411The C<new> method returns a blessed hash reference containing the following 488The C<new> method returns a blessed hash reference containing the following

Legend:
Removed from v.455  
changed lines
  Added in v.818

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9