Parent Directory
|
Revision Log
Revision 4091 - (view) (download) (as text)
| 1 : | sh002i | 440 | ################################################################################ |
| 2 : | sh002i | 1663 | # WeBWorK Online Homework Delivery System |
| 3 : | sh002i | 3973 | # Copyright © 2000-2006 The WeBWorK Project, http://openwebwork.sf.net/ |
| 4 : | gage | 4091 | # $CVSHeader: webwork-modperl/lib/WeBWorK/PG.pm,v 1.63 2006/01/25 23:13:51 sh002i Exp $ |
| 5 : | sh002i | 1663 | # |
| 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 | ||
| 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. | ||
| 10 : | # | ||
| 11 : | # This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 : | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
| 13 : | # FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the | ||
| 14 : | # Artistic License for more details. | ||
| 15 : | sh002i | 440 | ################################################################################ |
| 16 : | |||
| 17 : | sh002i | 424 | package WeBWorK::PG; |
| 18 : | sh002i | 414 | |
| 19 : | sh002i | 455 | =head1 NAME |
| 20 : | |||
| 21 : | sh002i | 1244 | WeBWorK::PG - Invoke one of several PG rendering methods using an easy-to-use |
| 22 : | API. | ||
| 23 : | sh002i | 455 | |
| 24 : | =cut | ||
| 25 : | |||
| 26 : | sh002i | 414 | use strict; |
| 27 : | use warnings; | ||
| 28 : | sh002i | 1557 | use WeBWorK::PG::ImageGenerator; |
| 29 : | use WeBWorK::Utils qw(runtime_use formatDateTime makeTempDirectory); | ||
| 30 : | sh002i | 414 | |
| 31 : | sh002i | 2192 | use constant DISPLAY_MODES => { |
| 32 : | # display name # mode name | ||
| 33 : | tex => "TeX", | ||
| 34 : | plainText => "HTML", | ||
| 35 : | formattedText => "HTML_tth", | ||
| 36 : | images => "HTML_dpng", | ||
| 37 : | jsMath => "HTML_jsMath", | ||
| 38 : | dpvc | 2200 | asciimath => "HTML_asciimath", |
| 39 : | sh002i | 2192 | }; |
| 40 : | |||
| 41 : | sh002i | 1196 | sub new { |
| 42 : | sh002i | 1244 | shift; # throw away invocant -- we don't need it |
| 43 : | my ($ce, $user, $key, $set, $problem, $psvn, $formFields, | ||
| 44 : | $translationOptions) = @_; | ||
| 45 : | sh002i | 415 | |
| 46 : | sh002i | 1244 | my $renderer = $ce->{pg}->{renderer}; |
| 47 : | sh002i | 562 | |
| 48 : | sh002i | 1244 | runtime_use $renderer; |
| 49 : | sh002i | 414 | |
| 50 : | sh002i | 1244 | return $renderer->new(@_); |
| 51 : | sh002i | 414 | } |
| 52 : | |||
| 53 : | sh002i | 1557 | sub defineProblemEnvir { |
| 54 : | my ( | ||
| 55 : | $self, | ||
| 56 : | $ce, | ||
| 57 : | $user, | ||
| 58 : | $key, | ||
| 59 : | $set, | ||
| 60 : | $problem, | ||
| 61 : | $psvn, | ||
| 62 : | $formFields, | ||
| 63 : | $options, | ||
| 64 : | ) = @_; | ||
| 65 : | |||
| 66 : | my %envir; | ||
| 67 : | |||
| 68 : | # ---------------------------------------------------------------------- | ||
| 69 : | |||
| 70 : | # PG environment variables | ||
| 71 : | # from docs/pglanguage/pgreference/environmentvariables as of 06/25/2002 | ||
| 72 : | # any changes are noted by "ADDED:" or "REMOVED:" | ||
| 73 : | |||
| 74 : | # Vital state information | ||
| 75 : | sh002i | 2192 | # ADDED: displayModeFailover, displayHintsQ, displaySolutionsQ, |
| 76 : | # refreshMath2img, texDisposition | ||
| 77 : | sh002i | 1557 | |
| 78 : | sh002i | 2192 | $envir{psvn} = $set->psvn; |
| 79 : | $envir{psvnNumber} = $envir{psvn}; | ||
| 80 : | $envir{probNum} = $problem->problem_id; | ||
| 81 : | $envir{questionNumber} = $envir{probNum}; | ||
| 82 : | $envir{fileName} = $problem->source_file; | ||
| 83 : | $envir{probFileName} = $envir{fileName}; | ||
| 84 : | $envir{problemSeed} = $problem->problem_seed; | ||
| 85 : | $envir{displayMode} = translateDisplayModeNames($options->{displayMode}); | ||
| 86 : | $envir{languageMode} = $envir{displayMode}; | ||
| 87 : | $envir{outputMode} = $envir{displayMode}; | ||
| 88 : | $envir{displayHintsQ} = $options->{showHints}; | ||
| 89 : | $envir{displaySolutionsQ} = $options->{showSolutions}; | ||
| 90 : | $envir{texDisposition} = "pdf"; # in webwork2, we use pdflatex | ||
| 91 : | sh002i | 1557 | |
| 92 : | # Problem Information | ||
| 93 : | # ADDED: courseName, formatedDueDate | ||
| 94 : | |||
| 95 : | $envir{openDate} = $set->open_date; | ||
| 96 : | sh002i | 2776 | $envir{formattedOpenDate} = formatDateTime($envir{openDate}, $ce->{siteDefaults}{timezone}); |
| 97 : | sh002i | 1557 | $envir{dueDate} = $set->due_date; |
| 98 : | sh002i | 2776 | $envir{formattedDueDate} = formatDateTime($envir{dueDate}, $ce->{siteDefaults}{timezone}); |
| 99 : | sh002i | 1557 | $envir{formatedDueDate} = $envir{formattedDueDate}; # typo in many header files |
| 100 : | $envir{answerDate} = $set->answer_date; | ||
| 101 : | sh002i | 2776 | $envir{formattedAnswerDate} = formatDateTime($envir{answerDate}, $ce->{siteDefaults}{timezone}); |
| 102 : | sh002i | 1557 | $envir{numOfAttempts} = ($problem->num_correct || 0) + ($problem->num_incorrect || 0); |
| 103 : | $envir{problemValue} = $problem->value; | ||
| 104 : | $envir{sessionKey} = $key; | ||
| 105 : | $envir{courseName} = $ce->{courseName}; | ||
| 106 : | |||
| 107 : | # Student Information | ||
| 108 : | # ADDED: studentID | ||
| 109 : | |||
| 110 : | $envir{sectionName} = $user->section; | ||
| 111 : | $envir{sectionNumber} = $envir{sectionName}; | ||
| 112 : | $envir{recitationName} = $user->recitation; | ||
| 113 : | $envir{recitationNumber} = $envir{recitationName}; | ||
| 114 : | $envir{setNumber} = $set->set_id; | ||
| 115 : | $envir{studentLogin} = $user->user_id; | ||
| 116 : | $envir{studentName} = $user->first_name . " " . $user->last_name; | ||
| 117 : | $envir{studentID} = $user->student_id; | ||
| 118 : | |||
| 119 : | # Answer Information | ||
| 120 : | # REMOVED: refSubmittedAnswers | ||
| 121 : | |||
| 122 : | $envir{inputs_ref} = $formFields; | ||
| 123 : | |||
| 124 : | # External Programs | ||
| 125 : | # ADDED: externalLaTeXPath, externalDvipngPath, | ||
| 126 : | # externalGif2EpsPath, externalPng2EpsPath | ||
| 127 : | |||
| 128 : | $envir{externalTTHPath} = $ce->{externalPrograms}->{tth}; | ||
| 129 : | $envir{externalLaTeXPath} = $ce->{externalPrograms}->{latex}; | ||
| 130 : | $envir{externalDvipngPath} = $ce->{externalPrograms}->{dvipng}; | ||
| 131 : | $envir{externalGif2EpsPath} = $ce->{externalPrograms}->{gif2eps}; | ||
| 132 : | $envir{externalPng2EpsPath} = $ce->{externalPrograms}->{png2eps}; | ||
| 133 : | $envir{externalGif2PngPath} = $ce->{externalPrograms}->{gif2png}; | ||
| 134 : | |||
| 135 : | # Directories and URLs | ||
| 136 : | # REMOVED: courseName | ||
| 137 : | # ADDED: dvipngTempDir | ||
| 138 : | dpvc | 2166 | # ADDED: jsMathURL |
| 139 : | dpvc | 2200 | # ADDED: asciimathURL |
| 140 : | sh002i | 3355 | # ADDED: macrosPath |
| 141 : | # REMOVED: macrosDirectory, courseScriptsDirectory | ||
| 142 : | sh002i | 1557 | |
| 143 : | $envir{cgiDirectory} = undef; | ||
| 144 : | $envir{cgiURL} = undef; | ||
| 145 : | $envir{classDirectory} = undef; | ||
| 146 : | gage | 4091 | $envir{macrosPath} = $ce->{pg}->{directories}{macrosPath}; |
| 147 : | $envir{appletDirs} = $ce->{pg}->{directories}{appletDirs}; | ||
| 148 : | sh002i | 1557 | $envir{htmlDirectory} = $ce->{courseDirs}->{html}."/"; |
| 149 : | $envir{htmlURL} = $ce->{courseURLs}->{html}."/"; | ||
| 150 : | $envir{templateDirectory} = $ce->{courseDirs}->{templates}."/"; | ||
| 151 : | $envir{tempDirectory} = $ce->{courseDirs}->{html_temp}."/"; | ||
| 152 : | $envir{tempURL} = $ce->{courseURLs}->{html_temp}."/"; | ||
| 153 : | $envir{scriptDirectory} = undef; | ||
| 154 : | $envir{webworkDocsURL} = $ce->{webworkURLs}->{docs}."/"; | ||
| 155 : | jj | 2170 | $envir{localHelpURL} = $ce->{webworkURLs}->{local_help}."/"; |
| 156 : | dpvc | 3224 | $envir{jsMathURL} = $ce->{webworkURLs}->{jsMath}; |
| 157 : | dpvc | 2200 | $envir{asciimathURL} = $ce->{webworkURLs}->{asciimath}; |
| 158 : | sh002i | 1557 | |
| 159 : | # Information for sending mail | ||
| 160 : | |||
| 161 : | $envir{mailSmtpServer} = $ce->{mail}->{smtpServer}; | ||
| 162 : | $envir{mailSmtpSender} = $ce->{mail}->{smtpSender}; | ||
| 163 : | $envir{ALLOW_MAIL_TO} = $ce->{mail}->{allowedRecipients}; | ||
| 164 : | |||
| 165 : | # Default values for evaluating answers | ||
| 166 : | |||
| 167 : | my $ansEvalDefaults = $ce->{pg}->{ansEvalDefaults}; | ||
| 168 : | $envir{$_} = $ansEvalDefaults->{$_} foreach (keys %$ansEvalDefaults); | ||
| 169 : | |||
| 170 : | # ---------------------------------------------------------------------- | ||
| 171 : | |||
| 172 : | my $basename = "equation-$envir{psvn}.$envir{probNum}"; | ||
| 173 : | $basename .= ".$envir{problemSeed}" if $envir{problemSeed}; | ||
| 174 : | sh002i | 2440 | |
| 175 : | # to make grabbing these options easier, we'll pull them out now... | ||
| 176 : | my %imagesModeOptions = %{$ce->{pg}->{displayModeOptions}->{images}}; | ||
| 177 : | |||
| 178 : | sh002i | 1557 | # Object for generating equation images |
| 179 : | $envir{imagegen} = WeBWorK::PG::ImageGenerator->new( | ||
| 180 : | tempDir => $ce->{webworkDirs}->{tmp}, # global temp dir | ||
| 181 : | latex => $envir{externalLaTeXPath}, | ||
| 182 : | dvipng => $envir{externalDvipngPath}, | ||
| 183 : | useCache => 1, | ||
| 184 : | cacheDir => $ce->{webworkDirs}->{equationCache}, | ||
| 185 : | cacheURL => $ce->{webworkURLs}->{equationCache}, | ||
| 186 : | cacheDB => $ce->{webworkFiles}->{equationCacheDB}, | ||
| 187 : | sh002i | 2440 | useMarkers => ($imagesModeOptions{dvipng_align} && $imagesModeOptions{dvipng_align} eq 'mysql'), |
| 188 : | dvipng_align => $imagesModeOptions{dvipng_align}, | ||
| 189 : | dvipng_depth_db => $imagesModeOptions{dvipng_depth_db}, | ||
| 190 : | sh002i | 1557 | ); |
| 191 : | dpvc | 2983 | |
| 192 : | # ADDED: jsMath options | ||
| 193 : | $envir{jsMath} = {%{$ce->{pg}{displayModeOptions}{jsMath}}}; | ||
| 194 : | sh002i | 1557 | |
| 195 : | # Other things... | ||
| 196 : | $envir{QUIZ_PREFIX} = $options->{QUIZ_PREFIX}; # used by quizzes | ||
| 197 : | $envir{PROBLEM_GRADER_TO_USE} = $ce->{pg}->{options}->{grader}; | ||
| 198 : | $envir{PRINT_FILE_NAMES_FOR} = $ce->{pg}->{specialPGEnvironmentVars}->{PRINT_FILE_NAMES_FOR}; | ||
| 199 : | dpvc | 2699 | |
| 200 : | # ADDED: __files__ | ||
| 201 : | # an array for mapping (eval nnn) to filenames in error messages | ||
| 202 : | $envir{__files__} = { | ||
| 203 : | root => $ce->{webworkDirs}{root}, # used to shorten filenames | ||
| 204 : | pg => $ce->{pg}{directories}{root}, # ditto | ||
| 205 : | tmpl => $ce->{courseDirs}{templates}, # ditto | ||
| 206 : | }; | ||
| 207 : | sh002i | 1557 | |
| 208 : | jj | 2217 | # variables for interpreting capa problems and other things to be |
| 209 : | # seen in a pg file | ||
| 210 : | my $specialPGEnvironmentVarHash = $ce->{pg}->{specialPGEnvironmentVars}; | ||
| 211 : | for my $SPGEV (keys %{$specialPGEnvironmentVarHash}) { | ||
| 212 : | $envir{$SPGEV} = $specialPGEnvironmentVarHash->{$SPGEV}; | ||
| 213 : | } | ||
| 214 : | sh002i | 1557 | |
| 215 : | return \%envir; | ||
| 216 : | } | ||
| 217 : | |||
| 218 : | sub translateDisplayModeNames($) { | ||
| 219 : | my $name = shift; | ||
| 220 : | sh002i | 2192 | return DISPLAY_MODES()->{$name}; |
| 221 : | sh002i | 1557 | } |
| 222 : | |||
| 223 : | sub oldSafetyFilter { | ||
| 224 : | my $answer = shift; # accepts one answer and checks it | ||
| 225 : | my $submittedAnswer = $answer; | ||
| 226 : | $answer = '' unless defined $answer; | ||
| 227 : | my ($errorno); | ||
| 228 : | $answer =~ tr/\000-\037/ /; | ||
| 229 : | # Return if answer field is empty | ||
| 230 : | unless ($answer =~ /\S/) { | ||
| 231 : | #$errorno = "<BR>No answer was submitted."; | ||
| 232 : | $errorno = 0; ## don't report blank answer as error | ||
| 233 : | return ($answer,$errorno); | ||
| 234 : | } | ||
| 235 : | # replace ^ with ** (for exponentiation) | ||
| 236 : | # $answer =~ s/\^/**/g; | ||
| 237 : | # Return if forbidden characters are found | ||
| 238 : | unless ($answer =~ /^[a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\[\]\(\)\,\|]+$/ ) { | ||
| 239 : | $answer =~ tr/a-zA-Z0-9_\-\+ \t\/@%\*\.\n^\(\)/#/c; | ||
| 240 : | $errorno = "<BR>There are forbidden characters in your answer: $submittedAnswer<BR>"; | ||
| 241 : | return ($answer,$errorno); | ||
| 242 : | } | ||
| 243 : | $errorno = 0; | ||
| 244 : | return($answer, $errorno); | ||
| 245 : | } | ||
| 246 : | |||
| 247 : | sub nullSafetyFilter { | ||
| 248 : | return shift, 0; # no errors | ||
| 249 : | } | ||
| 250 : | |||
| 251 : | sh002i | 414 | 1; |
| 252 : | sh002i | 440 | |
| 253 : | __END__ | ||
| 254 : | |||
| 255 : | =head1 SYNOPSIS | ||
| 256 : | |||
| 257 : | $pg = WeBWorK::PG->new( | ||
| 258 : | sh002i | 1239 | $ce, # a WeBWorK::CourseEnvironment object |
| 259 : | sh002i | 818 | $user, # a WeBWorK::DB::Record::User object |
| 260 : | sh002i | 440 | $sessionKey, |
| 261 : | sh002i | 818 | $set, # a WeBWorK::DB::Record::UserSet object |
| 262 : | $problem, # a WeBWorK::DB::Record::UserProblem object | ||
| 263 : | sh002i | 502 | $psvn, |
| 264 : | $formFields # in &WeBWorK::Form::Vars format | ||
| 265 : | sh002i | 440 | { # translation options |
| 266 : | displayMode => "images", # (plainText|formattedText|images) | ||
| 267 : | showHints => 1, # (0|1) | ||
| 268 : | showSolutions => 0, # (0|1) | ||
| 269 : | refreshMath2img => 0, # (0|1) | ||
| 270 : | processAnswers => 1, # (0|1) | ||
| 271 : | }, | ||
| 272 : | ); | ||
| 273 : | |||
| 274 : | $translator = $pg->{translator}; # WeBWorK::PG::Translator | ||
| 275 : | $body = $pg->{body_text}; # text string | ||
| 276 : | $header = $pg->{head_text}; # text string | ||
| 277 : | $answerHash = $pg->{answers}; # WeBWorK::PG::AnswerHash | ||
| 278 : | $result = $pg->{result}; # hash reference | ||
| 279 : | $state = $pg->{state}; # hash reference | ||
| 280 : | $errors = $pg->{errors}; # text string | ||
| 281 : | $warnings = $pg->{warnings}; # text string | ||
| 282 : | $flags = $pg->{flags}; # hash reference | ||
| 283 : | |||
| 284 : | =head1 DESCRIPTION | ||
| 285 : | |||
| 286 : | sh002i | 1244 | WeBWorK::PG is a factory for modules which use the WeBWorK::PG API. Notable |
| 287 : | modules which use this API (and exist) are WeBWorK::PG::Local and | ||
| 288 : | WeBWorK::PG::Remote. The course environment key $pg{renderer} is consulted to | ||
| 289 : | determine which render to use. | ||
| 290 : | sh002i | 440 | |
| 291 : | sh002i | 1244 | =head1 THE WEBWORK::PG API |
| 292 : | sh002i | 440 | |
| 293 : | sh002i | 1244 | Modules which support this API must implement the following method: |
| 294 : | |||
| 295 : | sh002i | 440 | =over |
| 296 : | |||
| 297 : | sh002i | 1557 | =item new ENVIRONMENT, USER, KEY, SET, PROBLEM, PSVN, FIELDS, OPTIONS |
| 298 : | sh002i | 440 | |
| 299 : | The C<new> method creates a translator, initializes it using the parameters | ||
| 300 : | specified, translates a PG file, and processes answers. It returns a reference | ||
| 301 : | to a blessed hash containing the results of the translation process. | ||
| 302 : | |||
| 303 : | =back | ||
| 304 : | |||
| 305 : | =head2 Parameters | ||
| 306 : | |||
| 307 : | =over | ||
| 308 : | |||
| 309 : | =item ENVIRONMENT | ||
| 310 : | |||
| 311 : | a WeBWorK::CourseEnvironment object | ||
| 312 : | |||
| 313 : | =item USER | ||
| 314 : | |||
| 315 : | sh002i | 502 | a WeBWorK::User object |
| 316 : | sh002i | 440 | |
| 317 : | =item KEY | ||
| 318 : | |||
| 319 : | the session key of the current session | ||
| 320 : | |||
| 321 : | =item SET | ||
| 322 : | |||
| 323 : | sh002i | 502 | a WeBWorK::Set object |
| 324 : | sh002i | 440 | |
| 325 : | =item PROBLEM | ||
| 326 : | |||
| 327 : | sh002i | 818 | a WeBWorK::DB::Record::UserProblem object. The contents of the source_file |
| 328 : | field can specify a PG file either by absolute path or path relative to the | ||
| 329 : | "templates" directory. I<The caller should remove taint from this value before | ||
| 330 : | passing!> | ||
| 331 : | sh002i | 440 | |
| 332 : | sh002i | 502 | =item PSVN |
| 333 : | |||
| 334 : | the problem set version number | ||
| 335 : | |||
| 336 : | =item FIELDS | ||
| 337 : | |||
| 338 : | a reference to a hash (as returned by &WeBWorK::Form::Vars) containing form | ||
| 339 : | fields submitted by a problem processor. The translator will look for fields | ||
| 340 : | like "AnSwEr[0-9]" containing submitted student answers. | ||
| 341 : | |||
| 342 : | sh002i | 440 | =item OPTIONS |
| 343 : | |||
| 344 : | a reference to a hash containing the following data: | ||
| 345 : | |||
| 346 : | =over | ||
| 347 : | |||
| 348 : | =item displayMode | ||
| 349 : | |||
| 350 : | one of "plainText", "formattedText", or "images" | ||
| 351 : | |||
| 352 : | =item showHints | ||
| 353 : | |||
| 354 : | boolean, render hints | ||
| 355 : | |||
| 356 : | =item showSolutions | ||
| 357 : | |||
| 358 : | boolean, render solutions | ||
| 359 : | |||
| 360 : | =item refreshMath2img | ||
| 361 : | |||
| 362 : | boolean, force images created by math2img (in "images" mode) to be recreated, | ||
| 363 : | sh002i | 1244 | even if the PG source has not been updated. FIXME: remove this option. |
| 364 : | sh002i | 440 | |
| 365 : | =item processAnswers | ||
| 366 : | |||
| 367 : | boolean, call answer evaluators and graders | ||
| 368 : | |||
| 369 : | =back | ||
| 370 : | |||
| 371 : | =back | ||
| 372 : | |||
| 373 : | =head2 RETURN VALUE | ||
| 374 : | |||
| 375 : | The C<new> method returns a blessed hash reference containing the following | ||
| 376 : | fields. More information can be found in the documentation for | ||
| 377 : | WeBWorK::PG::Translator. | ||
| 378 : | |||
| 379 : | =over | ||
| 380 : | |||
| 381 : | =item translator | ||
| 382 : | |||
| 383 : | The WeBWorK::PG::Translator object used to render the problem. | ||
| 384 : | |||
| 385 : | =item head_text | ||
| 386 : | |||
| 387 : | HTML code for the E<lt>headE<gt> block of an resulting web page. Used for | ||
| 388 : | JavaScript features. | ||
| 389 : | |||
| 390 : | =item body_text | ||
| 391 : | |||
| 392 : | HTML code for the E<lt>bodyE<gt> block of an resulting web page. | ||
| 393 : | |||
| 394 : | =item answers | ||
| 395 : | |||
| 396 : | An C<AnswerHash> object containing submitted answers, and results of answer | ||
| 397 : | evaluation. | ||
| 398 : | |||
| 399 : | =item result | ||
| 400 : | |||
| 401 : | A hash containing the results of grading the problem. | ||
| 402 : | |||
| 403 : | =item state | ||
| 404 : | |||
| 405 : | A hash containing the new problem state. | ||
| 406 : | |||
| 407 : | =item errors | ||
| 408 : | |||
| 409 : | A string containing any errors encountered while rendering the problem. | ||
| 410 : | |||
| 411 : | =item warnings | ||
| 412 : | |||
| 413 : | A string containing any warnings encountered while rendering the problem. | ||
| 414 : | |||
| 415 : | =item flags | ||
| 416 : | |||
| 417 : | A hash containing PG_flags (see the Translator docs). | ||
| 418 : | |||
| 419 : | =back | ||
| 420 : | |||
| 421 : | sh002i | 1557 | =head1 METHODS PROVIDED BY THE BASE CLASS |
| 422 : | |||
| 423 : | The following methods are provided for use by subclasses of WeBWorK::PG. | ||
| 424 : | |||
| 425 : | =over | ||
| 426 : | |||
| 427 : | =item defineProblemEnvir ENVIRONMENT, USER, KEY, SET, PROBLEM, PSVN, FIELDS, OPTIONS | ||
| 428 : | |||
| 429 : | Generate a problem environment hash to pass to the renderer. | ||
| 430 : | |||
| 431 : | =item translateDisplayModeNames NAME | ||
| 432 : | |||
| 433 : | NAME contains | ||
| 434 : | |||
| 435 : | =back | ||
| 436 : | |||
| 437 : | sh002i | 440 | =head1 AUTHOR |
| 438 : | |||
| 439 : | Written by Sam Hathaway, sh002i (at) math.rochester.edu. | ||
| 440 : | |||
| 441 : | =cut |
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |