11
22=head1 NAME
33
4- PGProblemCritic - Parse a PG program and analyze the contents for good and bad features.
4+ PGProblemCritic - Parse a PG program and analyze the contents for positive and negative features.
55
66=head1 DESCRIPTION
77
@@ -80,17 +80,27 @@ sub analyzePGcode ($code) {
8080 # default flags for presence of features in a PG problem
8181 my $features = {
8282 metadata => { DBsubject => 0, DBchapter => 0, DBsection => 0, KEYWORDS => 0 },
83- good => {
83+ positive => {
8484 PGML => 0,
8585 solution => 0,
8686 hint => 0,
87- scaffold => 0,
8887 custom_checker => 0,
8988 multianswer => 0,
90- answer_hints => 0,
91- nicetable => 0,
89+ nicetables => 0,
90+ contexts => { BaseN => 0, Units => 0, Boolean => 0, Reaction => 0 },
91+ parsers =>
92+ { dropdown => 0, RadioButtons => 0, CheckboxList => 0, RadioMultianswer => 0, GraphTool => 0 },
93+ macros => {
94+ randomPerson => 0,
95+ Plots => 0,
96+ PGtikz => 0,
97+ Plotly3D => 0,
98+ PGlateximage => 0,
99+ Scaffold => 0,
100+ AnswerHints => 0,
101+ }
92102 },
93- bad => {
103+ negative => {
94104 BEGIN_TEXT => 0,
95105 beginproblem => 0,
96106 oldtable => 0,
@@ -100,8 +110,8 @@ sub analyzePGcode ($code) {
100110 context_texstrings => 0,
101111 multiple_loadmacros => 0,
102112 showPartialCorrect => 0,
103- old_multiple_choice => 0,
104113 lines_below_enddocument => 0,
114+ macros => { PGgraphmacros => 0, PGchoicemacros => 0 }
105115 },
106116 deprecated_macros => [],
107117 macros => []
@@ -129,12 +139,12 @@ sub analyzePGcode ($code) {
129139 # Skip any full-line comments.
130140 next if $line =~ / ^\s *#/ ;
131141
132- $features -> {good }{solution } = 1 if $line =~ / BEGIN_(PGML_)?SOLUTION/ ;
133- $features -> {good }{hint } = 1 if $line =~ / BEGIN_(PGML_)?HINT/ ;
142+ $features -> {positive }{solution } = 1 if $line =~ / BEGIN_(PGML_)?SOLUTION/ ;
143+ $features -> {positive }{hint } = 1 if $line =~ / BEGIN_(PGML_)?HINT/ ;
134144
135145 # Analyze the loadMacros info.
136146 if ($line =~ / loadMacros\( / ) {
137- $features -> {bad }{multiple_loadmacros } = 1 if $loadmacros_parsed == 1;
147+ $features -> {negative }{multiple_loadmacros } = 1 if $loadmacros_parsed == 1;
138148 $loadmacros_parsed = 1;
139149 # Parse the macros, which may be on multiple rows.
140150 my $macros = $line ;
@@ -161,7 +171,7 @@ sub analyzePGcode ($code) {
161171 push (@{ $features -> {deprecated_macros } }, $macro ) if (grep { $macro eq $_ } @$all_deprecated_macros );
162172 }
163173 } elsif ($line =~ / BEGIN_PGML(_SOLUTION|_HINT)?/ ) {
164- $features -> {good }{PGML } = 1;
174+ $features -> {positive }{PGML } = 1;
165175 my @pgml_lines ;
166176 while (1) {
167177 $line = shift @pglines ;
@@ -170,40 +180,62 @@ sub analyzePGcode ($code) {
170180 }
171181
172182 my $pgml_features = analyzePGMLBlock(@pgml_lines );
173- $features -> {bad }{missing_alt_tag } = 1 if $pgml_features -> {missing_alt_tag };
183+ $features -> {negative }{missing_alt_tag } = 1 if $pgml_features -> {missing_alt_tag };
174184 }
175185
176186 if ($line =~ / ENDDOCUMENT/ ) { # scan if there are any lines below the ENDDOCUMENT
177187
178188 do {
179189 $line = shift @pglines ;
180190 last unless defined ($line );
181- $features -> {bad }{lines_below_enddocument } = 1 if $line !~ / ^\s *$ / ;
191+ $features -> {negative }{lines_below_enddocument } = 1 if $line !~ / ^\s *$ / ;
182192 } while (defined ($line ));
183193 }
184194
185- # Check for bad features.
186- $features -> {bad }{beginproblem } = 1 if $line =~ / beginproblem\(\) / ;
187- $features -> {bad }{BEGIN_TEXT } = 1 if $line =~ / (BEGIN_(TEXT|HINT|SOLUTION))|EV[23]/ ;
188- $features -> {bad }{context_texstrings } = 1 if $line =~ / ->(texStrings|normalStrings)/ ;
195+ # Check for negative features.
196+ $features -> {negative }{beginproblem } = 1 if $line =~ / beginproblem\(\) / ;
197+ $features -> {negative }{BEGIN_TEXT } = 1 if $line =~ / (BEGIN_(TEXT|HINT|SOLUTION))|EV[23]/ ;
198+ $features -> {negative }{context_texstrings } = 1 if $line =~ / ->(texStrings|normalStrings)/ ;
189199 for (qw( num str fun) ) {
190- $features -> {bad }{ $_ . ' _cmp' } = 1 if $line =~ / ${_}_cmp\( / ;
200+ $features -> {negative }{ $_ . ' _cmp' } = 1 if $line =~ / ${_}_cmp\( / ;
191201 }
192- $features -> {bad }{oldtable } = 1 if $line =~ / BeginTable/i ;
193- $features -> {bad }{showPartialCorrect } = 1 if $line =~ / \$ showPartialCorrectAnswers\s =\s 1/ ;
194- $features -> {bad }{old_multiple_choice } = 1
202+ $features -> {negative }{oldtable } = 1 if $line =~ / BeginTable/i ;
203+ $features -> {negative }{showPartialCorrect } = 1 if $line =~ / \$ showPartialCorrectAnswers\s =\s 1/ ;
204+ $features -> {negative }{macros }{PGgraphmacros } = 1 if $line =~ / init_graph\( / ;
205+ $features -> {negative }{macros }{PGchoicemacros } = 1
195206 if $line =~ / new_checkbox_multiple_choice/
196207 || $line =~ / new_match_list/
197208 || $line =~ / new_select_list/
198209 || $line =~ / new_multiple_choice/
199210 || $line =~ / qa\s\( / ;
200211
201- # check for good features
202- $features -> {good }{scaffold } = 1 if $line =~ / Scaffold::Begin/ ;
203- $features -> {good }{answer_hints } = 1 if $line =~ / AnswerHints/ ;
204- $features -> {good }{multianswer } = 1 if $line =~ / MultiAnswer/ ;
205- $features -> {good }{custom_checker } = 1 if $line =~ / checker =>/ ;
206- $features -> {good }{nicetables } = 1 if $line =~ / DataTable|LayoutTable/ ;
212+ # check for positive features
213+ # macros:
214+ $features -> {positive }{macros }{Scaffold } = 1 if $line =~ / Scaffold::Begin/ ;
215+ $features -> {positive }{macros }{Plots } = 1 if $line =~ / Plot\( / ;
216+ $features -> {positive }{macros }{Plotly3D } = 1 if $line =~ / Graph3D\( / ;
217+ $features -> {positive }{macros }{PGtikz } = 1 if $line =~ / createTikZImage\( / ;
218+ $features -> {positive }{macros }{AnswerHints } = 1 if $line =~ / AnswerHints/ ;
219+ $features -> {positive }{macros }{randomPerson } = 1 if $line =~ / randomPerson\( / || $line =~ / randomLastName\( / ;
220+ $features -> {positive }{macros }{PGlateximage } = 1 if $line =~ / createLaTeXImage\( / ;
221+
222+ # contexts:
223+
224+ $features -> {positive }{contexts }{Units } = 1 if $line =~ / Context\( ['"]Units['"]\) / ;
225+ $features -> {positive }{contexts }{BaseN } = 1 if $line =~ / Context\( ['"](Limited)?BaseN['"]\) / ;
226+ $features -> {positive }{contexts }{Boolean } = 1 if $line =~ / Context\( ['"]Boolean['"]\) / ;
227+ $features -> {positive }{contexts }{Reaction } = 1 if $line =~ / Context\( ['"]Reaction['"]\) / ;
228+
229+ # parsers:
230+ $features -> {positive }{parsers }{PopUp } = 1 if $line =~ / DropDown\( / ;
231+ $features -> {positive }{parsers }{RadioButtons } = 1 if $line =~ / RadioButtons\( / ;
232+ $features -> {positive }{parsers }{CheckboxList } = 1 if $line =~ / CheckboxList\( / ;
233+ $features -> {positive }{parsers }{GraphTool } = 1 if $line =~ / GraphTool\( / ;
234+
235+ # other:
236+ $features -> {positive }{multianswer } = 1 if $line =~ / MultiAnswer/ ;
237+ $features -> {positive }{custom_checker } = 1 if $line =~ / checker\s *=>/ ;
238+ $features -> {positive }{nicetables } = 1 if $line =~ / DataTable|LayoutTable/ ;
207239
208240 }
209241 return $features ;
0 commit comments