[system] / trunk / pg / macros / PG.pl Repository:
ViewVC logotype

Diff of /trunk/pg/macros/PG.pl

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

Revision 5626 Revision 5658
1################################################################################ 1################################################################################
2# WeBWorK Online Homework Delivery System 2# WeBWorK Online Homework Delivery System
3# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ 3# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: pg/macros/PG.pl,v 1.34 2007/10/25 17:11:59 sh002i Exp $ 4# $CVSHeader: pg/macros/PG.pl,v 1.35 2008/03/26 02:43:07 gage Exp $
5# 5#
6# This program is free software; you can redistribute it and/or modify it under 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 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 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. 9# version, or (b) the "Artistic License" which comes with this package.
105 105
106#package PG; 106#package PG;
107 107
108# Private variables for the PG.pl file. 108# Private variables for the PG.pl file.
109 109
110my ($STRINGforOUTPUT, $STRINGforHEADER_TEXT, @PG_ANSWERS, @PG_UNLABELED_ANSWERS); 110# ^variable $STRINGforOUTPUT
111my $STRINGforOUTPUT;
112# ^variable $STRINGforHEADER_TEXT
113my $STRINGforHEADER_TEXT;
114# ^variable @PG_ANSWERS
115my @PG_ANSWERS;
116# ^variable @PG_UNLABELED_ANSWERS
117my @PG_UNLABELED_ANSWERS;
118# ^variable %PG_ANSWERS_HASH
111my %PG_ANSWERS_HASH ; 119my %PG_ANSWERS_HASH;
120
121# ^variable $PG_STOP_FLAG
112our $PG_STOP_FLAG; 122our $PG_STOP_FLAG;
113 123
114# my variables are unreliable if two DOCUMENTS were to be called before an ENDDOCUMENT 124# my variables are unreliable if two DOCUMENTS were to be called before an ENDDOCUMENT
115# there could be conflicts. As I understand the behavior of the Apache child 125# there could be conflicts. As I understand the behavior of the Apache child
116# this cannot occur -- a child finishes with one request before obtaining the next 126# this cannot occur -- a child finishes with one request before obtaining the next
141 151
142See also SRAND() in the L<PGbasicmacros.pl> file. 152See also SRAND() in the L<PGbasicmacros.pl> file.
143 153
144=cut 154=cut
145 155
156# ^function DOCUMENT
157# ^uses $STRINGforOUTPUT
158# ^uses $STRINGforHEADER_TEXT
159# ^uses @PG_ANSWERS
160# ^uses $PG_STOP_FLAG
161# ^uses @PG_UNLABELED_ANSWERS
162# ^uses %PG_ANSWERS_HASH
163# ^uses @PG_ANSWER_ENTRY_ORDER
164# ^uses $ANSWER_PREFIX
165# ^uses %PG_FLAGS
166# ^uses $showPartialCorrectAnswers
167# ^uses $showHints
168# ^uses $solutionExists
169# ^uses $hintExists
170# ^uses $pgComment
171# ^uses %gifs_created
172# ^uses %envir
173# ^uses $refSubmittedAnswers
174# ^uses @submittedAnswers
175# ^uses $PG_original_problemSeed
176# ^uses $problemSeed
177# ^uses $PG_random_generator
178# ^uses $ans_rule_count
179# ^uses $QUIZ_PREFIX
180# (Also creates a package scalar named after each key in %envir containing a copy of the corresponding value.)
181# ^uses &PGrandom::new
146sub DOCUMENT { 182sub DOCUMENT {
147 183
148 $STRINGforOUTPUT =""; 184 $STRINGforOUTPUT ="";
149 $STRINGforHEADER_TEXT =""; 185 $STRINGforHEADER_TEXT ="";
150 @PG_ANSWERS=(); 186 @PG_ANSWERS=();
260introduced between the existing content of the header text string and the new 296introduced between the existing content of the header text string and the new
261content being appended. 297content being appended.
262 298
263=cut 299=cut
264 300
301# ^function HEADER_TEXT
302# ^uses $STRINGforHEADER_TEXT
265sub HEADER_TEXT { 303sub HEADER_TEXT {
266 my @in = @_; 304 my @in = @_;
267 $STRINGforHEADER_TEXT .= join(" ",@in); 305 $STRINGforHEADER_TEXT .= join(" ",@in);
268 } 306 }
269 307
288introduced between the existing content of the header text string and the new 326introduced between the existing content of the header text string and the new
289content being appended. 327content being appended.
290 328
291=cut 329=cut
292 330
331# ^function TEXT
332# ^uses $PG_STOP_FLAG
333# ^uses $STRINGforOUTPUT
293sub TEXT { 334sub TEXT {
294 return "" if $PG_STOP_FLAG; 335 return "" if $PG_STOP_FLAG;
295 my @in = @_; 336 my @in = @_;
296 $STRINGforOUTPUT .= join(" ",@in); 337 $STRINGforOUTPUT .= join(" ",@in);
297} 338}
311evaluator generator such as the cmp() method of MathObjects or the num_cmp() 352evaluator generator such as the cmp() method of MathObjects or the num_cmp()
312macro in L<PGanswermacros.pl>. 353macro in L<PGanswermacros.pl>.
313 354
314=cut 355=cut
315 356
357# ^function ANS
358# ^uses $PG_STOP_FLAG
359# ^uses @PG_ANSWERS
316sub ANS{ 360sub ANS{
317 return "" if $PG_STOP_FLAG; 361 return "" if $PG_STOP_FLAG;
318 my @in = @_; 362 my @in = @_;
319 while (@in ) { 363 while (@in ) {
320 warn("<BR><B>Error in ANS:$in[0]</B> -- inputs must be references to 364 warn("<BR><B>Error in ANS:$in[0]</B> -- inputs must be references to
334order entered. This allows pairing of answer evaluators and answer rules that 378order entered. This allows pairing of answer evaluators and answer rules that
335may not have been entered in the same order. 379may not have been entered in the same order.
336 380
337=cut 381=cut
338 382
383# ^function LABELED_ANS
384# ^uses &NAMED_ANS
339sub LABELED_ANS { 385sub LABELED_ANS {
340 &NAMED_ANS; 386 &NAMED_ANS;
341} 387}
342 388
343=item NAMED_ANS() 389=item NAMED_ANS()
344 390
345Old name for LABELED_ANS(). DEPRECATED. 391Old name for LABELED_ANS(). DEPRECATED.
346 392
347=cut 393=cut
348 394
395# ^function NAMED_ANS
396# ^uses $PG_STOP_FLAG
349sub NAMED_ANS{ 397sub NAMED_ANS{
350 return "" if $PG_STOP_FLAG; 398 return "" if $PG_STOP_FLAG;
351 my @in = @_; 399 my @in = @_;
352 while (@in ) { 400 while (@in ) {
353 my $label = shift @in; 401 my $label = shift @in;
367Temporarily suspends accumulation of problem text and storing of answer blanks 415Temporarily suspends accumulation of problem text and storing of answer blanks
368and answer evaluators until RESUME_RENDERING() is called. 416and answer evaluators until RESUME_RENDERING() is called.
369 417
370=cut 418=cut
371 419
420# ^function STOP_RENDERING
421# ^uses $PG_STOP_FLAG
372sub STOP_RENDERING { 422sub STOP_RENDERING {
373 $PG_STOP_FLAG=1; 423 $PG_STOP_FLAG=1;
374 ""; 424 "";
375} 425}
376 426
381Resumes accumulating problem text and storing answer blanks and answer 431Resumes accumulating problem text and storing answer blanks and answer
382evaluators. Reverses the effect of STOP_RENDERING(). 432evaluators. Reverses the effect of STOP_RENDERING().
383 433
384=cut 434=cut
385 435
436# ^function RESUME_RENDERING
437# ^uses $PG_STOP_FLAG
386sub RESUME_RENDERING { 438sub RESUME_RENDERING {
387 $PG_STOP_FLAG=0; 439 $PG_STOP_FLAG=0;
388 ""; 440 "";
389} 441}
390 442
482 534
483=back 535=back
484 536
485=cut 537=cut
486 538
539# ^function ENDDOCUMENT
540# ^uses @PG_UNLABELED_ANSWERS
541# ^uses %PG_ANSWERS_HASH
542# ^uses @PG_ANSWERS
487sub ENDDOCUMENT { 543sub ENDDOCUMENT {
488 544
489 my $index=0; 545 my $index=0;
490 foreach my $label (@PG_UNLABELED_ANSWERS) { 546 foreach my $label (@PG_UNLABELED_ANSWERS) {
491 if ( defined($PG_ANSWERS[$index]) ) { 547 if ( defined($PG_ANSWERS[$index]) ) {
577defined ($ans_rule_count) and returns the new count. This should only be used 633defined ($ans_rule_count) and returns the new count. This should only be used
578when one is about to define a new answer blank, for example with NEW_ANS_NAME(). 634when one is about to define a new answer blank, for example with NEW_ANS_NAME().
579 635
580=cut 636=cut
581 637
638# ^function inc_ans_rule_count
639# ^uses $ans_rule_count
582sub inc_ans_rule_count { 640sub inc_ans_rule_count {
583 eval(q!++$main::ans_rule_count!); # evalute at runtime to get correct main:: 641 eval(q!++$main::ans_rule_count!); # evalute at runtime to get correct main::
584} 642}
585 643
586=item RECORD_ANS_NAME() 644=item RECORD_ANS_NAME()
590Records the label for an answer blank. Used internally by L<PGbasicmacros.pl> 648Records the label for an answer blank. Used internally by L<PGbasicmacros.pl>
591to record the order of explicitly-labelled answer blanks. 649to record the order of explicitly-labelled answer blanks.
592 650
593=cut 651=cut
594 652
653# ^function RECORD_ANS_NAME
654# ^uses $PG_STOP_FLAG
655# ^uses @PG_ANSWER_ENTRY_ORDER
595sub RECORD_ANS_NAME { 656sub RECORD_ANS_NAME {
596 return "" if $PG_STOP_FLAG; 657 return "" if $PG_STOP_FLAG;
597 my $label = shift; 658 my $label = shift;
598 eval(q!push(@main::PG_ANSWER_ENTRY_ORDER, $label)!); 659 eval(q!push(@main::PG_ANSWER_ENTRY_ORDER, $label)!);
599 $label; 660 $label;
607added to the list of implicity-labeled answers. Used internally by 668added to the list of implicity-labeled answers. Used internally by
608L<PGbasicmacros.pl> to generate labels for unlabeled answer blanks. 669L<PGbasicmacros.pl> to generate labels for unlabeled answer blanks.
609 670
610=cut 671=cut
611 672
673# ^function NEW_ANS_NAME
674# ^uses $PG_STOP_FLAG
675# ^uses $QUIZ_PREFIX
676# ^uses $ANSWER_PREFIX
677# ^uses @PG_UNLABELED_ANSWERS
612sub NEW_ANS_NAME { 678sub NEW_ANS_NAME {
613 return "" if $PG_STOP_FLAG; 679 return "" if $PG_STOP_FLAG;
614 my $number=shift; 680 my $number=shift;
615 my $prefix = eval(q!$main::QUIZ_PREFIX.$main::ANSWER_PREFIX!); 681 my $prefix = eval(q!$main::QUIZ_PREFIX.$main::ANSWER_PREFIX!);
616 my $label = $prefix.$number; 682 my $label = $prefix.$number;
629the same label, but the label should only be added to the list of implicitly- 695the same label, but the label should only be added to the list of implicitly-
630labeled answers once.) 696labeled answers once.)
631 697
632=cut 698=cut
633 699
700# ^function ANS_NUM_TO_NAME
701# ^uses $QUIZ_PREFIX
702# ^uses $ANSWER_PREFIX
634sub ANS_NUM_TO_NAME { 703sub ANS_NUM_TO_NAME {
635 my $number=shift; 704 my $number=shift;
636 my $label = eval(q!$main::QUIZ_PREFIX.$main::ANSWER_PREFIX!).$number; 705 my $label = eval(q!$main::QUIZ_PREFIX.$main::ANSWER_PREFIX!).$number;
637 $label; 706 $label;
638} 707}
646Stores the label of a form field in the "extra" answers list. This is used to 715Stores the label of a form field in the "extra" answers list. This is used to
647keep track of answer blanks that are not associated with an answer evaluator. 716keep track of answer blanks that are not associated with an answer evaluator.
648 717
649=cut 718=cut
650 719
720# ^function RECORD_FORM_LABEL
721# ^uses $PG_STOP_FLAG
722# ^uses @KEPT_EXTRA_ANSWERS
651sub RECORD_FORM_LABEL { # this stores form data (such as sticky answers), but does nothing more 723sub RECORD_FORM_LABEL { # this stores form data (such as sticky answers), but does nothing more
652 # it's a bit of hack since we are storing these in the KEPT_EXTRA_ANSWERS queue even if they aren't answers per se. 724 # it's a bit of hack since we are storing these in the KEPT_EXTRA_ANSWERS queue even if they aren't answers per se.
653 return "" if $PG_STOP_FLAG; 725 return "" if $PG_STOP_FLAG;
654 my $label = shift; # the label of the input box or textarea 726 my $label = shift; # the label of the input box or textarea
655 eval(q!push(@main::KEPT_EXTRA_ANSWERS, $label)!); #put the labels into the hash to be caught later for recording purposes 727 eval(q!push(@main::KEPT_EXTRA_ANSWERS, $label)!); #put the labels into the hash to be caught later for recording purposes
663Generates a new answer label for an array (vector) element and adds it to the 735Generates a new answer label for an array (vector) element and adds it to the
664list of implicitly-labeled answers. 736list of implicitly-labeled answers.
665 737
666=cut 738=cut
667 739
740# ^function NEW_ANS_ARRAY_NAME
741# ^uses $PG_STOP_FLAG
742# ^uses $QUIZ_PREFIX
743# ^uses @PG_UNLABELED_ANSWERS
668sub NEW_ANS_ARRAY_NAME { # this keeps track of the answers which are entered implicitly, 744sub NEW_ANS_ARRAY_NAME { # this keeps track of the answers which are entered implicitly,
669 # rather than with a specific label 745 # rather than with a specific label
670 return "" if $PG_STOP_FLAG; 746 return "" if $PG_STOP_FLAG;
671 my $number=shift; 747 my $number=shift;
672 $vecnum = 0; 748 $vecnum = 0;
685Generate an additional answer label for an existing array (vector) element and 761Generate an additional answer label for an existing array (vector) element and
686add it to the list of "extra" answers. 762add it to the list of "extra" answers.
687 763
688=cut 764=cut
689 765
766# ^function NEW_ANS_ARRAY_NAME_EXTENSION
767# ^uses $PG_STOP_FLAG
690sub NEW_ANS_ARRAY_NAME_EXTENSION { # this keeps track of the answers which are entered implicitly, 768sub NEW_ANS_ARRAY_NAME_EXTENSION { # this keeps track of the answers which are entered implicitly,
691 # rather than with a specific label 769 # rather than with a specific label
692 return "" if $PG_STOP_FLAG; 770 return "" if $PG_STOP_FLAG;
693 my $number=shift; 771 my $number=shift;
694 my $row = shift; 772 my $row = shift;
712 790
713 791
714 792
715=cut 793=cut
716 794
795# ^function get_PG_ANSWERS_HASH
796# ^uses %PG_ANSWERS_HASH
797# ^uses @PG_UNLABELED_ANSWERS
798# ^uses @PG_ANSWERS
717sub get_PG_ANSWERS_HASH { 799sub get_PG_ANSWERS_HASH {
718 # update the PG_ANSWWERS_HASH, then report the result. 800 # update the PG_ANSWWERS_HASH, then report the result.
719 # This is used in writing sequential problems 801 # This is used in writing sequential problems
720 # if there is an input, use that as a key into the answer hash 802 # if there is an input, use that as a key into the answer hash
721 my $key = shift; 803 my $key = shift;
749 a path relative to the top of the templates directory. The output 831 a path relative to the top of the templates directory. The output
750 of that problem appears in the given problem. 832 of that problem appears in the given problem.
751 833
752=cut 834=cut
753 835
836# ^function includePGproblem
837# ^uses %envir
838# ^uses &read_whole_problem_file
839# ^uses &includePGtext
754sub includePGproblem { 840sub includePGproblem {
755 my $filePath = shift; 841 my $filePath = shift;
756 my %save_envir = %main::envir; 842 my %save_envir = %main::envir;
757 my $fullfilePath = $main::envir{templateDirectory}.$filePath; 843 my $fullfilePath = $main::envir{templateDirectory}.$filePath;
758 my $r_string = read_whole_problem_file($fullfilePath); 844 my $r_string = read_whole_problem_file($fullfilePath);
781L<PGbasicmacros.pl>, L<PGanswermacros.pl>. 867L<PGbasicmacros.pl>, L<PGanswermacros.pl>.
782 868
783=cut 869=cut
784 870
7851; 8711;
786

Legend:
Removed from v.5626  
changed lines
  Added in v.5658

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9