| … | |
… | |
| 5 | |
5 | |
| 6 | package WeBWorK::PG; |
6 | package WeBWorK::PG; |
| 7 | |
7 | |
| 8 | =head1 NAME |
8 | =head1 NAME |
| 9 | |
9 | |
| 10 | WeBWorK::PG - Wrap the action of the PG Translator in an easy-to-use API |
10 | WeBWorK::PG - Wrap the action of the PG Translator in an easy-to-use API. |
| 11 | |
11 | |
| 12 | =cut |
12 | =cut |
| 13 | |
13 | |
| 14 | use strict; |
14 | use strict; |
| 15 | use warnings; |
15 | use warnings; |
| … | |
… | |
| 39 | my $user = $classlist->getUser($userName); |
39 | my $user = $classlist->getUser($userName); |
| 40 | my $set = $wwdb->getSet($userName, $setName); |
40 | my $set = $wwdb->getSet($userName, $setName); |
| 41 | my $problem = $wwdb->getProblem($userName, $setName, $problemNumber); |
41 | my $problem = $wwdb->getProblem($userName, $setName, $problemNumber); |
| 42 | my $psvn = $wwdb->getPSVN($userName, $setName); |
42 | my $psvn = $wwdb->getPSVN($userName, $setName); |
| 43 | |
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 | |
| 44 | # create a Translator |
48 | # create a Translator |
| 45 | warn "PG: creating a Translator\n"; |
49 | warn "PG: creating a Translator\n"; |
| 46 | my $translator = WeBWorK::PG::Translator->new; |
50 | my $translator = WeBWorK::PG::Translator->new; |
| 47 | |
51 | |
| 48 | # set the directory hash |
52 | # set the directory hash |
| … | |
… | |
| 55 | }); |
59 | }); |
| 56 | |
60 | |
| 57 | # evaluate modules and "extra packages" |
61 | # evaluate modules and "extra packages" |
| 58 | warn "PG: evaluating modules and \"extra packages\"\n"; |
62 | warn "PG: evaluating modules and \"extra packages\"\n"; |
| 59 | my @modules = @{ $courseEnv->{pg}->{modules} }; |
63 | my @modules = @{ $courseEnv->{pg}->{modules} }; |
| 60 | foreach my $module_packages (@modules) { |
64 | foreach my $module_packages_ref (@modules) { |
| 61 | # the first item in $module_packages is the main package |
65 | my ($module, @extra_packages) = @$module_packages_ref; |
|
|
66 | # the first item is the main package |
| 62 | $translator->evaluate_modules(shift @$module_packages); |
67 | $translator->evaluate_modules($module); |
| 63 | # the remaining items are "extra" packages |
68 | # the remaining items are "extra" packages |
| 64 | $translator->load_extra_packages(@$module_packages); |
69 | $translator->load_extra_packages(@extra_packages); |
| 65 | } |
70 | } |
| 66 | |
71 | |
| 67 | # set the environment (from defineProblemEnvir) |
72 | # set the environment (from defineProblemEnvir) |
| 68 | warn "PG: setting the environment (from defineProblemEnvir)\n"; |
73 | warn "PG: setting the environment (from defineProblemEnvir)\n"; |
| 69 | $translator->environment(defineProblemEnvir( |
74 | $translator->environment(defineProblemEnvir( |
| … | |
… | |
| 99 | |
104 | |
| 100 | # translate the PG source into text |
105 | # translate the PG source into text |
| 101 | warn "PG: translating the PG source into text\n"; |
106 | warn "PG: translating the PG source into text\n"; |
| 102 | $translator->translate(); |
107 | $translator->translate(); |
| 103 | |
108 | |
| 104 | # [in Problem.pm and processProblem8.pl, "install a grader" is here] |
109 | my ($result, $state); # we'll need these on the other side of the if block! |
| 105 | |
110 | if ($translationOptions->{processAnswers}) { |
|
|
111 | |
| 106 | # process student answers |
112 | # process student answers |
| 107 | warn "PG: processing student answers\n"; |
113 | warn "PG: processing student answers\n"; |
| 108 | $translator->process_answers($formFields); |
114 | $translator->process_answers($formFields); |
| 109 | |
115 | |
| 110 | # retrieve the problem state and give it to the translator |
116 | # retrieve the problem state and give it to the translator |
| 111 | warn "PG: retrieving the problem state and giving it to the translator\n"; |
117 | warn "PG: retrieving the problem state and giving it to the translator\n"; |
| 112 | $translator->rh_problem_state({ |
118 | $translator->rh_problem_state({ |
| 113 | recorded_score => $problem->status, |
119 | recorded_score => $problem->status, |
| 114 | num_of_correct_ans => $problem->num_correct, |
120 | num_of_correct_ans => $problem->num_correct, |
| 115 | num_of_incorrect_ans => $problem->num_incorrect, |
121 | num_of_incorrect_ans => $problem->num_incorrect, |
| 116 | }); |
122 | }); |
| 117 | |
123 | |
| 118 | # determine an entry order -- the ANSWER_ENTRY_ORDER flag is built by |
124 | # determine an entry order -- the ANSWER_ENTRY_ORDER flag is built by |
| 119 | # the PG macro package (PG.pl) |
125 | # the PG macro package (PG.pl) |
| 120 | warn "PG: determining an entry order\n"; |
126 | warn "PG: determining an entry order\n"; |
| 121 | my @answerOrder = |
127 | my @answerOrder = |
| 122 | $translator->rh_flags->{ANSWER_ENTRY_ORDER} |
128 | $translator->rh_flags->{ANSWER_ENTRY_ORDER} |
| 123 | ? @{ $translator->rh_flags->{ANSWER_ENTRY_ORDER} } |
129 | ? @{ $translator->rh_flags->{ANSWER_ENTRY_ORDER} } |
| 124 | : keys %{ $translator->rh_evaluated_answers }; |
130 | : keys %{ $translator->rh_evaluated_answers }; |
| 125 | |
131 | |
| 126 | # install a grader -- use the one specified in the problem, |
132 | # install a grader -- use the one specified in the problem, |
| 127 | # or fall back on the default from the course environment. |
133 | # or fall back on the default from the course environment. |
| 128 | # (two magic strings are accepted, to avoid having to |
134 | # (two magic strings are accepted, to avoid having to |
| 129 | # reference code when it would be difficult.) |
135 | # reference code when it would be difficult.) |
| 130 | warn "PG: installing a grader\n"; |
136 | warn "PG: installing a grader\n"; |
| 131 | my $grader = $translator->rh_flags->{PROBLEM_GRADER_TO_USE} |
137 | my $grader = $translator->rh_flags->{PROBLEM_GRADER_TO_USE} |
| 132 | || $courseEnv->{pg}->{options}->{grader}; |
138 | || $courseEnv->{pg}->{options}->{grader}; |
| 133 | $grader = $translator->rf_std_problem_grader |
139 | $grader = $translator->rf_std_problem_grader |
| 134 | if $grader eq "std_problem_grader"; |
140 | if $grader eq "std_problem_grader"; |
| 135 | $grader = $translator->rf_avg_problem_grader |
141 | $grader = $translator->rf_avg_problem_grader |
| 136 | if $grader eq "avg_problem_grader"; |
142 | if $grader eq "avg_problem_grader"; |
| 137 | die "Problem grader $grader is not a CODE reference." |
143 | die "Problem grader $grader is not a CODE reference." |
| 138 | unless ref $grader eq "CODE"; |
144 | unless ref $grader eq "CODE"; |
| 139 | $translator->rf_problem_grader($grader); |
145 | $translator->rf_problem_grader($grader); |
| 140 | |
146 | |
| 141 | # grade the problem |
147 | # grade the problem |
| 142 | warn "PG: grading the problem\n"; |
148 | warn "PG: grading the problem\n"; |
| 143 | my ($result, $state) = $translator->grade_problem( |
149 | ($result, $state) = $translator->grade_problem( |
| 144 | answers_submitted => $translationOptions->{processAnswers}, |
150 | answers_submitted => $translationOptions->{processAnswers}, |
| 145 | ANSWER_ENTRY_ORDER => \@answerOrder, |
151 | ANSWER_ENTRY_ORDER => \@answerOrder, |
| 146 | ); |
152 | ); |
|
|
153 | |
|
|
154 | } |
| 147 | |
155 | |
| 148 | # return an object which contains the translator and the results of |
156 | # return an object which contains the translator and the results of |
| 149 | # the translation process. this is DIFFERENT from the "format expected |
157 | # the translation process. this is DIFFERENT from the "format expected |
| 150 | # by Webwork.pm (and I believe processProblem8, but check.)" |
158 | # by Webwork.pm (and I believe processProblem8, but check.)" |
| 151 | return bless { |
159 | return bless { |
| … | |
… | |
| 180 | # PG environment variables |
188 | # PG environment variables |
| 181 | # from docs/pglanguage/pgreference/environmentvariables as of 06/25/2002 |
189 | # from docs/pglanguage/pgreference/environmentvariables as of 06/25/2002 |
| 182 | # any changes are noted by "ADDED:" or "REMOVED:" |
190 | # any changes are noted by "ADDED:" or "REMOVED:" |
| 183 | |
191 | |
| 184 | # Vital state information |
192 | # Vital state information |
| 185 | # ADDED: displayHintsQ, displaySolutionsQ |
193 | # ADDED: displayHintsQ, displaySolutionsQ, refreshMath2img |
| 186 | |
194 | |
| 187 | $envir{psvn} = $psvn; |
195 | $envir{psvn} = $psvn; |
| 188 | $envir{psvnNumber} = $envir{psvn}; |
196 | $envir{psvnNumber} = $envir{psvn}; |
| 189 | $envir{probNum} = $problem->id; |
197 | $envir{probNum} = $problem->id; |
| 190 | $envir{questionNumber} = $envir{probNum}; |
198 | $envir{questionNumber} = $envir{probNum}; |
| … | |
… | |
| 263 | } |
271 | } |
| 264 | |
272 | |
| 265 | sub translateDisplayModeNames($) { |
273 | sub translateDisplayModeNames($) { |
| 266 | my $name = shift; |
274 | my $name = shift; |
| 267 | return { |
275 | return { |
|
|
276 | tex => "TeX", |
| 268 | plainText => "HTML", |
277 | plainText => "HTML", |
| 269 | formattedText => "HTML_tth", |
278 | formattedText => "HTML_tth", |
| 270 | images => "HTML_img" |
279 | images => "HTML_img" |
| 271 | }->{$name}; |
280 | }->{$name}; |
| 272 | } |
281 | } |