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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1154 - (download) (as text) (annotate)
Fri Jun 13 02:30:45 2003 UTC (9 years, 11 months ago) by sh002i
File size: 20640 byte(s)
Rewrote ImageGenerator to work with WeBWorK2. Its arguments are now
passed in via an options hash instead of getting a whole %envir. Also,
the options are passed to the constructor and there is no initialize()
method. add() has the same interface, and render() has been changed
slightly. (This closes Bug #80!)

To make this work with 1.8, take a look at how I'm creating
ImageGenerator in &WeBWorK::PG::defineProblemEnvironment and make the
necessary modifications to processProblem8.pl.

I made changes to WeBWorK::PG to have "images" mode trigger HTML_dpng
rather than HTML_img, and also to create an ImageGenerator before
initializing and call render() after translation.

Also in PG, I shortened the names of the equation image files. They're
now "equation-$PSVN-$probnum-$seed.png". This has the added benefit of
forcing image regeneration if the problem seed changes, closing Bug
#70.

Equation files are now dumped directly into the $courseDirs{HTML_temp}
directory. This means that no one has to worry about whether "m2i"
exists any more.

global.conf.dist was changed to not include the switches to dvipng on
the command line (they're currently hardcoded into ImageGenerator).

I still have to get this to work with dvipng 0.3. I should also take
advantages of 0.3's new features, like pipelining (using the -follow
switch) and specifying the output file name (to avoid the "move" of
resulting images).

This is MUCH FASTER than the way I was calling dvipng, and I think it's
safe to say that it's a better method. Thanks JJ!
-sam

    1 ################################################################################
    2 # WeBWorK mod_perl (c) 2000-2002 WeBWorK Project
    3 # $Id$
    4 ################################################################################
    5 
    6 package WeBWorK::PG;
    7 
    8 =head1 NAME
    9 
   10 WeBWorK::PG - Wrap the action of the PG Translator in an easy-to-use API.
   11 
   12 =cut
   13 
   14 use strict;
   15 use warnings;
   16 use File::Path qw(rmtree);
   17 use WeBWorK::PG::ImageGenerator;
   18 use WeBWorK::PG::Translator;
   19 use WeBWorK::Utils qw(readFile formatDateTime writeTimingLogEntry makeTempDirectory);
   20 
   21 sub new($$$$$$$$) {
   22   my $invocant = shift;
   23   my $class = ref($invocant) || $invocant;
   24   my (
   25     $courseEnv,
   26     $user,
   27     $key,
   28     $set,
   29     $problem,
   30     $psvn,
   31     $formFields, # in CGI::Vars format
   32     $translationOptions, # hashref containing options for the
   33                          # translator, such as whether to show
   34              # hints and the display mode to use
   35   ) = @_;
   36 
   37   # write timing log entry
   38   writeTimingLogEntry($courseEnv, "WeBWorK::PG::new",
   39     "user=".$user->user_id.",problem=".$courseEnv->{courseName}."/".$set->set_id."/".$problem->problem_id.",mode=".$translationOptions->{displayMode},
   40     "begin");
   41 
   42   # install a local warn handler to collect warnings
   43   my $warnings = "";
   44   local $SIG{__WARN__} = sub { $warnings .= shift }
   45     if $courseEnv->{pg}->{options}->{catchWarnings};
   46 
   47   # create a Translator
   48   #warn "PG: creating a Translator\n";
   49   my $translator = WeBWorK::PG::Translator->new;
   50 
   51   # set the directory hash
   52   #warn "PG: setting the directory hash\n";
   53   $translator->rh_directories({
   54     courseScriptsDirectory => $courseEnv->{webworkDirs}->{macros},
   55     macroDirectory         => $courseEnv->{courseDirs}->{macros},
   56     templateDirectory      => $courseEnv->{courseDirs}->{templates},
   57     tempDirectory          => $courseEnv->{courseDirs}->{html_temp},
   58   });
   59 
   60   # evaluate modules and "extra packages"
   61   #warn "PG: evaluating modules and \"extra packages\"\n";
   62   my @modules = @{ $courseEnv->{pg}->{modules} };
   63   foreach my $module_packages_ref (@modules) {
   64     my ($module, @extra_packages) = @$module_packages_ref;
   65     # the first item is the main package
   66     $translator->evaluate_modules($module);
   67     # the remaining items are "extra" packages
   68     $translator->load_extra_packages(@extra_packages);
   69   }
   70 
   71   # set the environment (from defineProblemEnvir)
   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   );
   83   $translator->environment($envir);
   84 
   85   # initialize the Translator
   86   #warn "PG: initializing the Translator\n";
   87   $translator->initialize();
   88 
   89   # load IO.pl, PG.pl, and dangerousMacros.pl using unrestricted_load
   90   # i'd like to change this at some point to have the same sort of interface to global.conf
   91   # that the module loading does -- have a list of macros to load unrestrictedly.
   92   #warn "PG: loading IO.pl, PG.pl, and dangerousMacros.pl using unrestricted_load\n";
   93   foreach (qw(IO.pl PG.pl dangerousMacros.pl)) {
   94     my $macroPath = $courseEnv->{webworkDirs}->{macros} . "/$_";
   95     my $err = $translator->unrestricted_load($macroPath);
   96     warn "Error while loading $macroPath: $err" if $err;
   97   }
   98 
   99   # set the opcode mask (using default values)
  100   #warn "PG: setting the opcode mask (using default values)\n";
  101   $translator->set_mask();
  102 
  103   # store the problem source
  104   #warn "PG: storing the problem source\n";
  105   my $sourceFile = ( defined($translationOptions->{override_problem_source}) ) ?
  106             $translationOptions->{override_problem_source} :
  107             $problem->source_file;
  108   $sourceFile = $courseEnv->{courseDirs}->{templates}."/".$sourceFile
  109     unless ($sourceFile =~ /^\//);
  110   eval { $translator->source_string(readFile($sourceFile)) };
  111   if ($@) {
  112     # well, we couldn't get the problem source, for some reason.
  113     return bless {
  114       translator => $translator,
  115       head_text  => "",
  116       body_text  => <<EOF,
  117 WeBWorK::Utils::readFile($sourceFile) says:
  118 $@
  119 EOF
  120       answers    => {},
  121       result     => {},
  122       state      => {},
  123       errors     => "Failed to read the problem source file.",
  124       warnings   => $warnings,
  125       flags      => {error_flag => 1},
  126     }, $class;
  127   }
  128 
  129   # install a safety filter (&safetyFilter)
  130   #warn "PG: installing a safety filter\n";
  131   $translator->rf_safety_filter(\&safetyFilter);
  132 
  133   # write timing log entry -- the translator is now all set up
  134   writeTimingLogEntry($courseEnv, "WeBWorK::PG::new",
  135     "initialized",
  136     "intermediate");
  137 
  138   # translate the PG source into text
  139   #warn "PG: translating the PG source into text\n";
  140   $translator->translate();
  141 
  142   # after we're done translating, we may have to clean up after the
  143   # translator:
  144 
  145   # for example, HTML_img mode uses a tempdir for dvipng's temp files.\
  146   # We have to remove it.
  147   if ($envir->{dvipngTempDir}) {
  148     rmtree($envir->{dvipngTempDir}, 0, 0);
  149   }
  150 
  151   # HTML_dpng, on the other hand, uses an ImageGenerator. We have to
  152   # render the queued equations.
  153   if ($envir->{imagegen}) {
  154     my $sourceFile = $courseEnv->{courseDirs}->{templates} . "/" . $problem->source_file;
  155     my %mtimeOption = -e $sourceFile
  156       ? (mtime => (stat $sourceFile)[9])
  157       : ();
  158 
  159     $envir->{imagegen}->render(
  160       refresh => $translationOptions->{refreshMath2img},
  161       %mtimeOption,
  162     );
  163   }
  164 
  165   my ($result, $state); # we'll need these on the other side of the if block!
  166   if ($translationOptions->{processAnswers}) {
  167 
  168     # process student answers
  169     #warn "PG: processing student answers\n";
  170     $translator->process_answers($formFields);
  171 
  172     # retrieve the problem state and give it to the translator
  173     #warn "PG: retrieving the problem state and giving it to the translator\n";
  174     $translator->rh_problem_state({
  175       recorded_score =>       $problem->status,
  176       num_of_correct_ans =>   $problem->num_correct,
  177       num_of_incorrect_ans => $problem->num_incorrect,
  178     });
  179 
  180     # determine an entry order -- the ANSWER_ENTRY_ORDER flag is built by
  181     # the PG macro package (PG.pl)
  182     #warn "PG: determining an entry order\n";
  183     my @answerOrder =
  184       $translator->rh_flags->{ANSWER_ENTRY_ORDER}
  185         ? @{ $translator->rh_flags->{ANSWER_ENTRY_ORDER} }
  186         : keys %{ $translator->rh_evaluated_answers };
  187 
  188     # install a grader -- use the one specified in the problem,
  189     # or fall back on the default from the course environment.
  190     # (two magic strings are accepted, to avoid having to
  191     # reference code when it would be difficult.)
  192     #warn "PG: installing a grader\n";
  193     my $grader = $translator->rh_flags->{PROBLEM_GRADER_TO_USE}
  194       || $courseEnv->{pg}->{options}->{grader};
  195     $grader = $translator->rf_std_problem_grader
  196       if $grader eq "std_problem_grader";
  197     $grader = $translator->rf_avg_problem_grader
  198       if $grader eq "avg_problem_grader";
  199     die "Problem grader $grader is not a CODE reference."
  200       unless ref $grader eq "CODE";
  201     $translator->rf_problem_grader($grader);
  202 
  203     # grade the problem
  204     #warn "PG: grading the problem\n";
  205     ($result, $state) = $translator->grade_problem(
  206       answers_submitted  => $translationOptions->{processAnswers},
  207       ANSWER_ENTRY_ORDER => \@answerOrder,
  208     );
  209 
  210   }
  211 
  212   # write timing log entry
  213   writeTimingLogEntry($courseEnv, "WeBWorK::PG::new", "", "end");
  214 
  215   # return an object which contains the translator and the results of
  216   # the translation process. this is DIFFERENT from the "format expected
  217   # by Webwork.pm (and I believe processProblem8, but check.)"
  218   return bless {
  219     translator => $translator,
  220     head_text  => ${ $translator->r_header },
  221     body_text  => ${ $translator->r_text   },
  222     answers    => $translator->rh_evaluated_answers,
  223     result     => $result,
  224     state      => $state,
  225     errors     => $translator->errors,
  226     warnings   => $warnings,
  227     flags      => $translator->rh_flags,
  228   }, $class;
  229 }
  230 
  231 # -----
  232 
  233 sub defineProblemEnvir($$$$$$$) {
  234   my (
  235     $courseEnv,
  236     $user,
  237     $key,
  238     $set,
  239     $problem,
  240     $psvn,
  241     $formFields,
  242     $options,
  243   ) = @_;
  244 
  245   my %envir;
  246 
  247   # ----------------------------------------------------------------------
  248 
  249   # PG environment variables
  250   # from docs/pglanguage/pgreference/environmentvariables as of 06/25/2002
  251   # any changes are noted by "ADDED:" or "REMOVED:"
  252 
  253   # Vital state information
  254   # ADDED: displayHintsQ, displaySolutionsQ, refreshMath2img,
  255   #        texDisposition
  256 
  257   $envir{psvn}              = $psvn;
  258   $envir{psvnNumber}        = $envir{psvn};
  259   $envir{probNum}           = $problem->problem_id;
  260   $envir{questionNumber}    = $envir{probNum};
  261   $envir{fileName}          = $problem->source_file;
  262   $envir{probFileName}      = $envir{fileName};
  263   $envir{problemSeed}       = (defined($options->{override_seed}) ) ? $options->{override_seed} :$problem->problem_seed;
  264   $envir{displayMode}       = translateDisplayModeNames($options->{displayMode});
  265   $envir{languageMode}      = $envir{displayMode};
  266   $envir{outputMode}        = $envir{displayMode};
  267   $envir{displayHintsQ}     = $options->{showHints};
  268   $envir{displaySolutionsQ} = $options->{showSolutions};
  269   # FIXME: this is HTML_img specific
  270   #$envir{refreshMath2img}   = $options->{refreshMath2img};
  271   $envir{texDisposition}    = "pdf"; # in webwork-modperl, we use pdflatex
  272 
  273   # Problem Information
  274   # ADDED: courseName, formatedDueDate
  275 
  276   $envir{openDate}            = $set->open_date;
  277   $envir{formattedOpenDate}   = formatDateTime($envir{openDate});
  278   $envir{dueDate}             = $set->due_date;
  279   $envir{formattedDueDate}    = formatDateTime($envir{dueDate});
  280   $envir{formatedDueDate}     = $envir{formattedDueDate}; # typo in many header files
  281   $envir{answerDate}          = $set->answer_date;
  282   $envir{formattedAnswerDate} = formatDateTime($envir{answerDate});
  283   $envir{numOfAttempts}       = ($problem->num_correct || 0) + ($problem->num_incorrect || 0);
  284   $envir{problemValue}        = $problem->value;
  285   $envir{sessionKey}          = $key;
  286   $envir{courseName}          = $courseEnv->{courseName};
  287 
  288   # Student Information
  289   # ADDED: studentID
  290 
  291   $envir{sectionName}      = $user->section;
  292   $envir{sectionNumber}    = $envir{sectionName};
  293   $envir{recitationName}   = $user->recitation;
  294   $envir{recitationNumber} = $envir{recitationName};
  295   $envir{setNumber}        = $set->set_id;
  296   $envir{studentLogin}     = $user->user_id;
  297   $envir{studentName}      = $user->first_name . " " . $user->last_name;
  298   $envir{studentID}        = $user->student_id;
  299 
  300   # Answer Information
  301   # REMOVED: refSubmittedAnswers
  302 
  303   $envir{inputs_ref} = $formFields;
  304 
  305   # External Programs
  306   # ADDED: externalLaTeXPath, externalDvipngPath,
  307   #        externalGif2EpsPath, externalPng2EpsPath
  308 
  309   $envir{externalTTHPath}      = $courseEnv->{externalPrograms}->{tth};
  310   $envir{externalLaTeXPath}    = $courseEnv->{externalPrograms}->{latex};
  311   $envir{externalDvipngPath}   = $courseEnv->{externalPrograms}->{dvipng};
  312   $envir{externalGif2EpsPath}  = $courseEnv->{externalPrograms}->{gif2eps};
  313   $envir{externalPng2EpsPath}  = $courseEnv->{externalPrograms}->{png2eps};
  314   $envir{externalGif2PngPath}  = $courseEnv->{externalPrograms}->{gif2png};
  315 
  316   # Directories and URLs
  317   # REMOVED: courseName
  318   # ADDED: dvipngTempDir
  319 
  320   $envir{cgiDirectory}           = undef;
  321   $envir{cgiURL}                 = undef;
  322   $envir{classDirectory}         = undef;
  323   $envir{courseScriptsDirectory} = $courseEnv->{webworkDirs}->{macros}."/";
  324   $envir{htmlDirectory}          = $courseEnv->{courseDirs}->{html}."/";
  325   $envir{htmlURL}                = $courseEnv->{courseURLs}->{html}."/";
  326   $envir{macroDirectory}         = $courseEnv->{courseDirs}->{macros}."/";
  327   $envir{templateDirectory}      = $courseEnv->{courseDirs}->{templates}."/";
  328   $envir{tempDirectory}          = $courseEnv->{courseDirs}->{html_temp}."/";
  329   $envir{tempURL}                = $courseEnv->{courseURLs}->{html_temp}."/";
  330   $envir{scriptDirectory}        = undef;
  331   $envir{webworkDocsURL}         = $courseEnv->{webworkURLs}->{docs}."/";
  332   # FIXME: this is HTML_img mode-specific
  333   #$envir{dvipngTempDir}          = $options->{displayMode} eq 'images'
  334   # ? makeTempDirectory($envir{tempDirectory}, "webwork-dvipng")
  335   # : undef;
  336 
  337   # Information for sending mail
  338 
  339   $envir{mailSmtpServer} = $courseEnv->{mail}->{smtpServer};
  340   $envir{mailSmtpSender} = $courseEnv->{mail}->{smtpSender};
  341   $envir{ALLOW_MAIL_TO}  = $courseEnv->{mail}->{allowedRecipients};
  342 
  343   # Default values for evaluating answers
  344 
  345   my $ansEvalDefaults = $courseEnv->{pg}->{ansEvalDefaults};
  346   $envir{$_} = $ansEvalDefaults->{$_} foreach (keys %$ansEvalDefaults);
  347 
  348   # ----------------------------------------------------------------------
  349 
  350   # Object for generating equation images
  351   $envir{imagegen} = WeBWorK::PG::ImageGenerator->new(
  352     tempDir  => $courseEnv->{webworkDirs}->{tmp}, # global temp dir
  353     dir  => $envir{tempDirectory},
  354     url  => $envir{tempURL},
  355     #basename => "$envir{studentLogin}.$envir{setNumber}.$envir{probNum}",
  356     basename => "equation-$envir{psvn}.$envir{probNum}.$envir{problemSeed}",
  357     latex  => $envir{externalLaTeXPath},
  358     dvipng   => $envir{externalDvipngPath},
  359   );
  360 
  361   # Other things...
  362   $envir{QUIZ_PREFIX}              = $options->{QUIZ_PREFIX}; # used by quizzes
  363   $envir{PROBLEM_GRADER_TO_USE}    = $courseEnv->{pg}->{options}->{grader};
  364   $envir{PRINT_FILE_NAMES_FOR}     = $courseEnv->{pg}->{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR};
  365 
  366   # variables for interpreting capa problems.
  367   $envir{CAPA_Tools}               = $courseEnv->{pg}->{specialPGEnvironmentVars}->{CAPA_Tools};
  368   $envir{CAPA_MCTools}             = $courseEnv->{pg}->{specialPGEnvironmentVars}->{CAPA_MCTools};
  369   $envir{CAPA_Graphics_URL}        = $courseEnv->{pg}->{specialPGEnvironmentVars}->{CAPA_Graphics_URL};
  370   $envir{CAPA_GraphicsDirectory}   = $courseEnv->{pg}->{specialPGEnvironmentVars}->{CAPA_GraphicsDirectory};
  371 
  372   return \%envir;
  373 }
  374 
  375 sub translateDisplayModeNames($) {
  376   my $name = shift;
  377   return {
  378     tex           => "TeX",
  379     plainText     => "HTML",
  380     formattedText => "HTML_tth",
  381     images        => "HTML_dpng", # "HTML_img",
  382   }->{$name};
  383 }
  384 
  385 sub safetyFilter {
  386   my $answer = shift; # accepts one answer and checks it
  387   my $submittedAnswer = $answer;
  388   $answer = '' unless defined $answer;
  389   my ($errorno);
  390   $answer =~ tr/\000-\037/ /;
  391   # Return if answer field is empty
  392   unless ($answer =~ /\S/) {
  393     #$errorno = "<BR>No answer was submitted.";
  394     $errorno = 0;  ## don't report blank answer as error
  395     return ($answer,$errorno);
  396   }
  397   # replace ^ with **    (for exponentiation)
  398   # $answer =~ s/\^/**/g;
  399   # Return if forbidden characters are found
  400   unless ($answer =~ /^[a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\[\]\(\)\,\|]+$/ )  {
  401     $answer =~ tr/a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)/#/c;
  402     $errorno = "<BR>There are forbidden characters in your answer: $submittedAnswer<BR>";
  403     return ($answer,$errorno);
  404   }
  405   $errorno = 0;
  406   return($answer, $errorno);
  407 }
  408 
  409 1;
  410 
  411 __END__
  412 
  413 =head1 SYNOPSIS
  414 
  415  $pg = WeBWorK::PG->new(
  416    $courseEnv,  # a WeBWorK::CourseEnvironment object
  417    $user,       # a WeBWorK::DB::Record::User object
  418    $sessionKey,
  419    $set,        # a WeBWorK::DB::Record::UserSet object
  420    $problem,    # a WeBWorK::DB::Record::UserProblem object
  421    $psvn,
  422    $formFields  # in &WeBWorK::Form::Vars format
  423    { # translation options
  424      displayMode     => "images", # (plainText|formattedText|images)
  425      showHints       => 1,        # (0|1)
  426      showSolutions   => 0,        # (0|1)
  427      refreshMath2img => 0,        # (0|1)
  428      processAnswers  => 1,        # (0|1)
  429    },
  430  );
  431 
  432  $translator = $pg->{translator}; # WeBWorK::PG::Translator
  433  $body       = $pg->{body_text};  # text string
  434  $header     = $pg->{head_text};  # text string
  435  $answerHash = $pg->{answers};    # WeBWorK::PG::AnswerHash
  436  $result     = $pg->{result};     # hash reference
  437  $state      = $pg->{state};      # hash reference
  438  $errors     = $pg->{errors};     # text string
  439  $warnings   = $pg->{warnings};   # text string
  440  $flags      = $pg->{flags};      # hash reference
  441 
  442 =head1 DESCRIPTION
  443 
  444 WeBWorK::PG encapsulates the PG translation process, making multiple calls to
  445 WeBWorK::PG::Translator. Much of the flexibility of the Translator is hidden,
  446 instead making choices that are appropriate for the webwork-modperl system.
  447 
  448 =head1 CONSTRUCTION
  449 
  450 =over
  451 
  452 =item new (ENVIRONMENT, USER, KEY, SET, PROBLEM, PSVN, FIELDS, OPTIONS)
  453 
  454 The C<new> method creates a translator, initializes it using the parameters
  455 specified, translates a PG file, and processes answers. It returns a reference
  456 to a blessed hash containing the results of the translation process.
  457 
  458 =back
  459 
  460 =head2 Parameters
  461 
  462 =over
  463 
  464 =item ENVIRONMENT
  465 
  466 a WeBWorK::CourseEnvironment object
  467 
  468 =item USER
  469 
  470 a WeBWorK::User object
  471 
  472 =item KEY
  473 
  474 the session key of the current session
  475 
  476 =item SET
  477 
  478 a WeBWorK::Set object
  479 
  480 =item PROBLEM
  481 
  482 a WeBWorK::DB::Record::UserProblem object. The contents of the source_file
  483 field can specify a PG file either by absolute path or path relative to the
  484 "templates" directory. I<The caller should remove taint from this value before
  485 passing!>
  486 
  487 =item PSVN
  488 
  489 the problem set version number
  490 
  491 =item FIELDS
  492 
  493 a reference to a hash (as returned by &WeBWorK::Form::Vars) containing form
  494 fields submitted by a problem processor. The translator will look for fields
  495 like "AnSwEr[0-9]" containing submitted student answers.
  496 
  497 =item OPTIONS
  498 
  499 a reference to a hash containing the following data:
  500 
  501 =over
  502 
  503 =item displayMode
  504 
  505 one of "plainText", "formattedText", or "images"
  506 
  507 =item showHints
  508 
  509 boolean, render hints
  510 
  511 =item showSolutions
  512 
  513 boolean, render solutions
  514 
  515 =item refreshMath2img
  516 
  517 boolean, force images created by math2img (in "images" mode) to be recreated,
  518 even if the PG source has not been updated. FIXME: change the name of this
  519 option to "refreshEquations" and update the docs accordingly.
  520 
  521 =item processAnswers
  522 
  523 boolean, call answer evaluators and graders
  524 
  525 =back
  526 
  527 =back
  528 
  529 =head2 RETURN VALUE
  530 
  531 The C<new> method returns a blessed hash reference containing the following
  532 fields. More information can be found in the documentation for
  533 WeBWorK::PG::Translator.
  534 
  535 =over
  536 
  537 =item translator
  538 
  539 The WeBWorK::PG::Translator object used to render the problem.
  540 
  541 =item head_text
  542 
  543 HTML code for the E<lt>headE<gt> block of an resulting web page. Used for
  544 JavaScript features.
  545 
  546 =item body_text
  547 
  548 HTML code for the E<lt>bodyE<gt> block of an resulting web page.
  549 
  550 =item answers
  551 
  552 An C<AnswerHash> object containing submitted answers, and results of answer
  553 evaluation.
  554 
  555 =item result
  556 
  557 A hash containing the results of grading the problem.
  558 
  559 =item state
  560 
  561 A hash containing the new problem state.
  562 
  563 =item errors
  564 
  565 A string containing any errors encountered while rendering the problem.
  566 
  567 =item warnings
  568 
  569 A string containing any warnings encountered while rendering the problem.
  570 
  571 =item flags
  572 
  573 A hash containing PG_flags (see the Translator docs).
  574 
  575 =back
  576 
  577 =head1 OPERATION
  578 
  579 WeBWorK::PG goes through the following operations when constructed:
  580 
  581 =over
  582 
  583 =item Get database information
  584 
  585 Retrieve information about the current user, set, and problem from the
  586 database.
  587 
  588 =item Create a translator
  589 
  590 Instantiate a WeBWorK::PG::Translator object.
  591 
  592 =item Set the directory hash
  593 
  594 Set the translator's directory hash (courseScripts, macros, templates, and temp
  595 directories) from the course environment.
  596 
  597 =item Evaluate PG modules
  598 
  599 Using the module list from the course environment (pg->modules), perform a
  600 "use"-like operation to evaluate modules at runtime.
  601 
  602 =item Set the problem environment
  603 
  604 Use data from the user, set, and problem, as well as the course environemnt and
  605 translation options, to set the problem environment.
  606 
  607 =item Initialize the translator
  608 
  609 Call &WeBWorK::PG::Translator::initialize. What more do you want?
  610 
  611 =item Load PG.pl and dangerousMacros.pl
  612 
  613 These macros must be loaded without opcode masking, so they are loaded here.
  614 
  615 =item Set the opcode mask
  616 
  617 Set the opcode mask to the default specified by WeBWorK::PG::Translator.
  618 
  619 =item Load the problem source
  620 
  621 Give the problem source to the translator.
  622 
  623 =item Install a safety filter
  624 
  625 The safety filter is used to preprocess student input before evaluation. The
  626 default safety filter, &WeBWorK::PG::safetyFilter, is used.
  627 
  628 =item Translate the problem source
  629 
  630 Call &WeBWorK::PG::Translator::translate to render the problem source into the
  631 format given by the display mode.
  632 
  633 =item Process student answers
  634 
  635 Use form field inputs to evaluate student answers.
  636 
  637 =item Load the problem state
  638 
  639 Use values from the database to initialize the problem state, so that the
  640 grader will have a point of reference.
  641 
  642 =item Determine an entry order
  643 
  644 Use the ANSWER_ENTRY_ORDER flag to determine the order of answers in the
  645 problem. This is important for problems with dependancies among parts.
  646 
  647 =item Install a grader
  648 
  649 Use the PROBLEM_GRADER_TO_USE flag, or a default from the course environment,
  650 to install a grader.
  651 
  652 =item Grade the problem
  653 
  654 Use the selected grader to grade the problem.
  655 
  656 =back
  657 
  658 =head1 AUTHOR
  659 
  660 Written by Sam Hathaway, sh002i (at) math.rochester.edu.
  661 
  662 =cut

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9