]> git.mjollnir.org Git - moodle.git/commitdiff
Integrated Multiple Answers and inline comments options. Made examples.txt. Documenta...
authorthetrinity <thetrinity>
Sat, 10 Jan 2004 03:35:11 +0000 (03:35 +0000)
committerthetrinity <thetrinity>
Sat, 10 Jan 2004 03:35:11 +0000 (03:35 +0000)
mod/quiz/format/gift/docs.html
mod/quiz/format/gift/format.php

index 634a71d90fbaf66f126e8f9f83d9096ba618098a..b7de1f042192dae013851938bc50c3ab9d37daba 100755 (executable)
@@ -1,125 +1,2 @@
-<html>
-
-    <head>
-        <meta http-equiv="content-type" content="text/html;charset=x-sjis">
-        <title>GIFT Import Filter Documentation</title>
-    </head>
-
-    <body bgcolor="#ffffff">
-        <h2>DESCRIPTION</h2>
-        <p>GIFT is a versitile import filter that provides a quick and easy method for teachers to write Moodle quiz questions as a text file. It supports multiple-choice, true-false, short answer and numerical questions, as well as insertion of a blank line for the missing word format. Below are examples of the following question types: multiple choice, missing word, true-false, short-answer and numerical.</p>
-<pre>     Who's buried in Grant's tomb?{~Grant ~Jefferson =no one}
-     
-     Grant is {~buried =entombed ~living} in Grant's tomb.
-     
-     Grant is buried in Grant's tomb.{FALSE}
-     
-     Who's buried in Grant's tomb?{=no one =nobody}
-
-     When was Ulysses S. Grant born?{#1922:1}</pre>
-        <p>Various question-types can be mixed in a sigle text file, and the format also supports question names, feedback comments and percentage-weight grades.</p>
-        <hr>
-        <p>
-        </p>
-        <h2>DOCUMENTATION</h2>
-        <p>
-        </p>
-        <p>GIFT is a versitile import filter that provides a quick and easy method for teachers to write Moodle quiz questions as a text file. GIFT can process four basic question types recognized by Moodle: Multiple Choice, True-False, Short Answer and Numerical. Various question-types can be mixed in a single text file, and the format also supports question names, feedback comments and percentage-weight grades.</p>
-        <p></p>
-        <h3>QUESTION TYPES</h3>
-
-        <p><u>Multiple Choice:</u><br />
-        For multiple choice questions, wrong answers are prefixed with a tilde (~) and the correct answer is prefixed with an equal sign (=).</p>
-        <pre>     Who's buried in Grant's tomb?{~Grant ~Jefferson =no one}</pre>
-        <p>The <b>Missing Word</b> format automatically inserts a fill-in-the-blank line (like this _____) in the middle of the sentence. To use the Misssing Word format, place the answers where you want the line to appear in the sentence.</p>
-        <pre>     Grant is {~buried =entombed ~living} in Grant's tomb.</pre>
-        <p>If the answers come before the closing punctuation mark, a fill-in-the-blank line will be inserted for the &quot;missing word&quot; format. All question types can be written in the Missing Word format.</p>
-        <p>There must be a blank line (double carriage return) seperating questions. For clarity, the answers can be written on seperate lines and even indented. For example:</p>
-<pre>     The American holiday of Thanksgiving is celebrated on the {
-         ~second
-         ~third
-         =fourth
-     } Thursday of November.
-     
-     Japanese characters originally came from what country? {
-         ~India
-         =China
-         ~Korea
-         ~Egypt}</pre>
-
-        <p><u>Short Answer:</u><br /> Answers in Short Answer question-type are all prefixed by an equal sign (=), indicating that they are all correct answers .The answers must not contain a tilde.</p>
-        <pre>     Who's buried in Grant's tomb?{=no one =nobody}
-
-     Two plus two equals {=four =4}.</pre>
-        <p>If there is only <u>one</u> correct Short Answer, it may be written without the equal sign prefix, as long as it cannot be confused as True-False.
-        <p><u>True-False:</u><br />
-            In this question-type the answer indicates whether the statement is true or false. The answer should be written as {TRUE} or {FALSE}, or abbreviated to {T} or {F}.</p>
-        <pre>     Grant is buried in Grant's tomb.{F}
-
-     The sun rises in the east.{T}</pre>
-
-        <p><u>Numerical:</u><br>
-            The answer section for Numerical questions must start with a number sign (#). Numerical answers can include an error margin, which is written following the correct answer, seperated by a colon. So for example, if the correct answer is anything between 1.5 and 2.5, then it would be written as follows <u>{#2:0.5}</u>. This indicates that 2 with an error margin of 0.5 is correct (i.e., the span from 1.5 to 2.5). If no error margin is specified, it will be assumed to be zero.</p>
-        <pre>     When was Ulysses S. Grant born? {#1922}
-
-     What is the value of pi (to 3 decimal places)? {#3.1415:0.0005}.</pre>
-         <p>Optionally, numerical answers can be written as a span in the following format {#<i>MinimumValue</i>..<i>MaximumValue</i>}.</p>
-        <pre>     What is the value of pi (to 3 decimal places)? {#3.141..3.142}.</pre>
-        <p>Moodle's browser interface does not support multiple numerical answers, but Moodle's code can and so does GIFT. This can be used to specify numerical multiple spans, and can be particularly usefully when combined with percentage weight grades. If multiple answers are used, they must be seperated by an equal sign, like short answer questions.</p>
-        <pre>     When was Ulysses S. Grant born? {#
-         =1922:0
-         =%50%1922:2}</pre>
-        <p>Note that since Moodle's browser GUI doesn't support multiple answers for Numerical questions, there's no way to see them or edit them through Moodle. The only way to change a numerical answer beyond the first, is to delete the question and re-import it (or use something like phpMyAdmin).</p>
-        <h3>OPTIONS</h3>
-        <p>In addition to these basic question types, this filter offers the following options: question name, feedback and percentage answer weight.</p>
-        <p><u>Question Name:</u><br /> A question name can be specified by placing it first and enclosing it within double colons.</p>
-<pre>     ::Kanji Origins::Japanese characters originally
-     came from what country? {=China}
-
-     ::Thanksgiving Date::The American holiday of Thanksgiving is 
-     celebrated on the {~second ~third =fourth} Thursday of November.</pre>
-        <p>If no question name is specified, the entire question will be used as the name by default.</p>
-<p><u>Feedback Comments:</u><br /> Feedback can be included for each answer by following the answer with a number sign (# also known as a hash mark) and the feedback.</p>
-<pre>     What's the answer to this multiple-choice question?{
-     ~wrong answer#comment on the wrong answer
-     ~another wrong answer#comment on this wrong answer
-     =right answer#Very good!}
-     
-     Who's buried in Grant's tomb?{
-     =no one#excellent answer!
-     =nobody#excellent answer!}
-     
-     Grant is buried in Grant's tomb.{FALSE#No one is buried in Grant's tomb.}</pre>
-
-<p>For Multiple Choice questions, feedback is displayed only for the answer the student selected. For short answer, feedback is shown only when students input the corresponding correct answer. For true-false questions, the imported feedback is saved so that it will display if the student marked the question incorrectly. So, in the last example above, the student would see the comment only if they selected TRUE as their answer.</p>
-
-<p><u>Percentage Answer Weights:</u><br />
-Percentage answer weights are available for both Multiple Choice and Short Answer questions. Percentage answer weights can be included by following the tilde (for Multiple Choice) or equal sign (for Short Answer) with the desired percent enclosed 
-within percent signs (e.g., %50%). This option can be combined with feedback comments.</p>
-<pre>     Difficult question.{~wrong answer ~%50%half credit answer =full credit answer}
-          
-     ::Jesus' hometown::Jesus Christ was from {
-     ~Jerusalem#This was an important city, but the wrong answer.
-     ~%25%Bethlehem#He was born here, but not raised here.
-     ~%50%Galilee#You need to be more specific.
-     =Nazareth#Yes! That's right!}.
-     
-     ::Jesus' hometown:: Jesus Christ was from {
-     =Nazareth#Yes! That's right!
-     =%75%Nazereth#Right, but misspelled.
-     =%25%Bethlehem#He was born here, but not raised here.}</pre>
-<p>Note that the last two examples are essentially the same question, first as multiple choice and then as short answer.</p>
-
-<p><small>Note that it is possible to specify percentage answer weights that are NOT available through the browser interface. Such answer-weights will calculate correctly (according to the value assigned when imported), and will appear normal to students taking the test. But such answer-weights will not display correctly to teachers when editing them through Moodle's Edit Question interface. The pull-down menu only allows certain fixed values, and if the answer-weight does not exactly match one of those predetermined values, then it will not display correctly. If you edit such a question through the browser interface, the answer weight will change to that displayed.</small></p>
-        <p><u>Other Options:</u><br />
-        Other options are avalable through editing the import filter <b>gift/format.php</b>. </p>
-        <p>Short Answer questions can be made case sensitive by changing &quot;0&quot; to &quot;1&quot; in the following line:<br />
-             <tt>$question-&gt;usecase = 0;  // Ignore case</tt></p>
-        <p>It is also possible to enable multiple answers, by uncommenting the appropriate code. Search for &quot;enable multiple answers&quot; to find the lines.</p>
-        <p> </p>
-        <h3>CREDITS</h3>
-        <p>This filter was written through the collaboration of numerous members of the Moodle community. It was originally based on the missingword format, which included code from Thomas Robb and others. Paul Tsuchido Shew wrote this filter in December 2003 incorporating community suggestions for a more robust question format. The name was conceived as an acronym for  &quot;General Import Format Technology&quot; or something like that, but it's too long for a simple filter like this, so it just GIFT.</p>
-        <p><small>GIFT documentation, version 1.2. Paul Tsuchido Shew, 6 Jan 2004.</small></p>
-</body>
-
-</html>
\ No newline at end of file
+this file discontinued
+(moved to help files)
\ No newline at end of file
index 9da01987367d91c108a3291cdd5140f11204427f..90089bfe4926fa99a8217470581f9af97f0ddc82 100755 (executable)
@@ -1,375 +1 @@
-<?php // $Id$
-//
-///////////////////////////////////////////////////////////////
-// GIFT
-//
-// The GIFT import filter is an easy to use method for teachers 
-// writing questions as a text file. It supports true-false, 
-// short answer, multiple-choice and numerical questions, as well 
-// as insertion of a blank line for the missing word format.
-//
-// Multiple Choice / Missing Word
-//     Who's buried in Grant's tomb?{~Grant ~Jefferson =no one}
-//     Grant is {~buried =entombed ~living} in Grant's tomb.
-// True-False:
-//     Grant is buried in Grant's tomb.{FALSE}
-// Short-Answer.
-//     Who's buried in Grant's tomb?{=no one =nobody}
-// Numerical
-//     When was Ulysses S. Grant born?{#1922:5}
-//
-// Optional question names are enclosed in double colon(::). 
-// Answer feedback is indicated with hash mark (#).
-// Percentage answer weights immediately follow the tilde (for
-// multiple choice) or equal sign (for short answer and numerical),
-// and are enclosed in percent signs (% %). Below are more
-// complicated examples with various options and formatting styles.
-// 
-//     ::Grant's Tomb::Grant is {
-//         ~buried#No one is buried there.
-//         =entombed#Right answer!
-//         ~living#We hope not!
-//     } in Grant's tomb.
-//
-//     Difficult multiple choice question.{
-//         ~wrong answer           #comment on wrong answer
-//         ~%50%half credit answer #comment on answer
-//         =full credit answer     #well done!}
-//
-//     ::Jesus' hometown (Short answer ex.):: Jesus Christ was from {
-//         =Nazareth#Yes! That's right!
-//         =%75%Nazereth#Right, but misspelled.
-//         =%25%Bethlehem#He was born here, but not raised here.
-//     }.
-//
-//     ::Numerical example::
-//     When was Ulysses S. Grant born? {#
-//         =1922:0      #Correct! 100% credit
-//         =%50%1922:2  #He was born in 1922.
-//                       You get 50% credit for being close.
-//      }
-// 
-// This filter was written through the collaboration of numerous 
-// members of the Moodle community. It was originally based on 
-// the missingword format, which included code from Thomas Robb
-// and others. Paul Tsuchido Shew wrote this filter in December 2003 
-// incorporating community suggestions for a more robust question format.
-// GIFT could stand for "General Import Format Technology" but that's
-// too long for a simple filter like this. It's just GIFT.
-//////////////////////////////////////////////////////////////////////////
-// Based on default.php, included by ../import.php
-
-class quiz_file_format extends quiz_default_format {
-
-    function answerweightparser(&$answer) {
-        $answer = substr($answer, 1);                        // removes initial %
-        $end_position  = strpos($answer, "%");
-        $answer_weight = substr($answer, 0, $end_position);  // gets weight as integer
-        $answer_weight = $answer_weight/100;                 // converts to percent
-        $answer = substr($answer, $end_position+1);          // removes comment from answer
-        // To enable multiple answers (if fractional answer weights are assigned) 
-        // uncomment the following three lines.
-        // if ($answer_weight > 0 and $answer_weight <> 1){
-        //     $question->single = 0; // ok many good answers
-        // }
-        return $answer_weight;
-    }
-
-
-    function commentparser(&$answer) {
-        if (strpos($answer,"#") > 0){
-            $hashpos = strpos($answer,"#");
-            $comment = addslashes(substr($answer, $hashpos+1));
-            $answer  = substr($answer, 0, $hashpos);
-        } else {
-            $comment = " ";
-        }
-        return $comment;
-    }
-    
-
-    function readquestion($lines) {
-    // Given an array of lines known to define a question in this format, this function
-    // converts it into a question object suitable for processing and insertion into Moodle.
-
-        $question = NULL;
-        $comment = NULL;
-        define("GIFT_ANSWERWEIGHT_REGEX", "^%\-*([0-9]{1,2})\.?([0-9]*)%");
-
-        $text = trim(implode(" ", $lines));
-
-        // QUESTION NAME parser
-        if (substr($text, 0, 2) == "::") {
-            $text = substr($text, 2);
-
-            $namefinish = strpos($text, "::");
-            if ($namefinish === false) {
-                $question->name = false;
-                // name will be assigned after processing question text below
-             } else {
-                $question->name = addslashes(trim(substr($text, 0, $namefinish)));
-                $text = trim(substr($text, $namefinish+2)); // Remove name from text
-            }
-        } else {
-            $question->name = false;
-        }
-
-
-        // FIND ANSWER section
-        $answerstart = strpos($text, "{");
-        if ($answerstart === false) {
-            if ($this->displayerrors) {
-                echo "<P>$text<P>Could not find a {";
-            }
-            return false;
-        }
-
-        $answerfinish = strpos($text, "}");
-        if ($answerfinish === false) {
-            if ($this->displayerrors) {
-                echo "<P>$text<P>Could not find a }";
-            }
-            return false;
-        }
-
-        $answerlength = $answerfinish - $answerstart;
-        $answertext = trim(substr($text, $answerstart + 1, $answerlength - 1));
-
-        // Format QUESTION TEXT without answer, inserting "_____" as necessary
-        if (substr($text, -1) == "}") {
-            // no blank line if answers follow question, outside of closing punctuation
-            $question->questiontext = addslashes(trim(substr_replace($text, "", $answerstart, $answerlength+1)));
-        } else {
-            // inserts blank line for missing word format
-            $question->questiontext = addslashes(trim(substr_replace($text, "_____", $answerstart, $answerlength+1)));
-        }
-
-        // set question name if not already set
-        if ($question->name === false) {
-            $question->name = $question->questiontext;
-            }
-
-
-         // determine QUESTION TYPE
-        $question->qtype = NULL;
-
-        if ($answertext{0} == "#"){
-            $question->qtype = NUMERICAL;
-
-        } elseif (strstr($answertext, "~") !== false)  {
-            // only Multiplechoice questions contain tilde ~
-            $question->qtype = MULTICHOICE;
-    
-        } else { // either TRUEFALSE or SHORTANSWER
-    
-            // TRUEFALSE question check
-            $truefalse_check = $answertext;
-            if (strpos($answertext,"#") > 0){ 
-                // strip comments to check for TrueFalse question
-                $truefalse_check = trim(substr($answertext, 0, strpos($answertext,"#")));
-            }
-
-            $valid_tf_answers = array("T", "TRUE", "F", "FALSE");
-            if (in_array($truefalse_check, $valid_tf_answers)) {
-                $question->qtype = TRUEFALSE;
-
-            } else { // Must be SHORTANSWER
-                    $question->qtype = SHORTANSWER;
-            }
-        }
-
-        if (!isset($question->qtype)) {
-            if ($this->displayerrors) {
-                echo "<P>$text<P>Question type not set.";
-                }
-            return false;
-        }
-
-        switch ($question->qtype) {
-            case MULTICHOICE:
-                $answertext = str_replace("=", "~=", $answertext);
-                $answers = explode("~", $answertext);
-                if (isset($answers[0])) {
-                    $answers[0] = trim($answers[0]);
-                }
-                if (empty($answers[0])) {
-                    array_shift($answers);
-                }
-    
-                $countanswers = count($answers);
-                if ($countanswers < 2) {
-                    if ($this->displayerrors) {
-                        echo "<P>$text<P>Found tilde for multiple choice, 
-                            but too few answers for Multiple Choice.<br />
-                            Found <u>$countanswers</u> answers in answertext.";
-                    }
-                    return false;
-                    break;
-                }
-    
-                $question->single = 1;   // Only one answer allowed by default
-
-                foreach ($answers as $key => $answer) {
-                    $answer = trim($answer);
-    
-                    // determine answer weight
-                    if ($answer[0] == "=") {
-                        $answer_weight = 1;
-                        $answer = substr($answer, 1);
-    
-                    } elseif (ereg(GIFT_ANSWERWEIGHT_REGEX, $answer)) {    // check for properly formatted answer weight
-                        $answer_weight = $this->answerweightparser($answer);
-                    
-                    } else {     //default, i.e., wrong anwer
-                        $answer_weight = 0;
-                    }
-                    $question->fraction[$key] = $answer_weight;
-                    $question->feedback[$key] = $this->commentparser($answer); // commentparser also removes comment from $answer
-                    $question->answer[$key]   = addslashes($answer);    
-                }  // end foreach answer
-    
-                $question->defaultgrade = 1;
-                $question->image = "";   // No images with this format
-                return $question;
-                break;
-            
-            case TRUEFALSE:
-                $answer = $answertext;
-                $comment = $this->commentparser($answer); // commentparser also removes comment from $answer
-
-                if ($answer == "T" OR $answer == "TRUE") {
-                    $question->answer = 1;
-                    $question->feedbackfalse = $comment; //feedback if answer is wrong
-                } else {
-                    $question->answer = 0;
-                    $question->feedbacktrue = $comment; //feedback if answer is wrong
-                }
-                $question->defaultgrade = 1;
-                $question->image = "";   // No images with this format
-                return $question;
-                break;
-                
-            case SHORTANSWER:
-                // SHORTANSWER Question
-                $answers = explode("=", $answertext);
-                if (isset($answers[0])) {
-                    $answers[0] = trim($answers[0]);
-                }
-                if (empty($answers[0])) {
-                    array_shift($answers);
-                }
-    
-                if (count($answers) == 0) {
-                    // invalid question
-                    if ($this->displayerrors) {
-                        echo "<P>$text<P>Found equals=, but no answers in answertext";
-                    }
-                    return false;
-                    break;
-                }
-
-                foreach ($answers as $key => $answer) {
-                    $answer = trim($answer);
-
-                    // Answer Weight
-                    if (ereg(GIFT_ANSWERWEIGHT_REGEX, $answer)) {    // check for properly formatted answer weight
-                        $answer_weight = $this->answerweightparser($answer);
-                    } else {     //default, i.e., full-credit anwer
-                        $answer_weight = 1;
-                    }
-                    $question->fraction[$key] = $answer_weight;
-                    $question->feedback[$key] = $this->commentparser($answer); //commentparser also removes comment from $answer
-                    $question->answer[$key]   = addslashes($answer);
-                }     // end foreach
-
-                $question->usecase = 0;  // Ignore case
-                $question->defaultgrade = 1;
-                $question->image = "";   // No images with this format
-                return $question;
-                break;
-
-            case NUMERICAL:
-                // Note similarities to ShortAnswer
-                $answertext = substr($answertext, 1); // remove leading "#"
-
-                $answers = explode("=", $answertext);
-                if (isset($answers[0])) {
-                    $answers[0] = trim($answers[0]);
-                }
-                if (empty($answers[0])) {
-                    array_shift($answers);
-                }
-    
-                if (count($answers) == 0) {
-                    // invalid question
-                    if ($this->displayerrors) {
-                        echo "<P>$text<P>No answers found in answertext (Numerical answer)";
-                    }
-                    return false;
-                    break;
-                }
-
-                foreach ($answers as $key => $answer) {
-                    $answer = trim($answer);
-
-                    // Answer weight
-                    if (ereg(GIFT_ANSWERWEIGHT_REGEX, $answer)) {    // check for properly formatted answer weight
-                        $answer_weight = $this->answerweightparser($answer);
-                    } else {     //default, i.e., full-credit anwer
-                        $answer_weight = 1;
-                    }
-                    $question->fraction[$key] = $answer_weight;
-                    $question->feedback[$key] = $this->commentparser($answer); //commentparser also removes comment from $answer
-
-                    //Calculate Answer and Min/Max values
-                    if (strpos($answer,"..") > 0) { // optional [min]..[max] format
-                        $marker                 = strpos($answer,"..");
-                        $question->max[$key]    = trim(substr($answer, $marker+2));
-                        $question->min[$key]    = trim(substr($answer, 0, $marker));
-                        $question->answer[$key] = ($question->max[$key] + $question->min[$key])/2;
-
-                    } elseif (strpos($answer,":") > 0){ // standard [answer]:[errormargin] format
-                        $marker                 = strpos($answer,":");
-                        $errormargin            = trim(substr($answer, $marker+1));
-                        $question->answer[$key] = trim(substr($answer, 0, $marker));
-                        $question->max[$key]    = $question->answer[$key] + $errormargin;
-                        $question->min[$key]    = $question->answer[$key] - $errormargin;
-
-                    } else { // only one valid answer (zero errormargin)
-                        $errormargin = 0;
-                        $question->answer[$key] = trim($answer);
-                        $question->max[$key]    = $question->answer[$key] + $errormargin;
-                        $question->min[$key]    = $question->answer[$key] - $errormargin;
-                    }
-    
-                    if (!is_numeric($question->answer[$key]) 
-                     OR !is_numeric($question->max[$key])
-                     OR !is_numeric($question->max[$key])) {
-                        if ($this->displayerrors) {
-                            echo "<P>$text<P>For numerical questions, answer must be numbers.
-                                <P>Answer: <u>$answer</u><P>ErrorMargin: <u>$errormargin</u> .";
-                        }
-                        return false;
-                        break;
-                    }
-
-                }     // end foreach
-
-                $question->defaultgrade = 1;
-                $question->image = "";   // No images with this format
-                return $question;
-                break;
-
-                default:
-                if ($this->displayerrors) {
-                    echo "<P>$text<P> No valid question type. Error in switch(question->qtype)";
-                }
-                return false;
-                break;                
-        
-        } // end switch ($question->qtype)
-
-    }    // end function readquestion($lines)
-}
-
-?>
+<?php // $Id$\r//\r///////////////////////////////////////////////////////////////\r// GIFT\r//\r// The GIFT import filter is an easy to use method for teachers \r// writing questions as a text file. It supports true-false, \r// short answer, multiple-choice and numerical questions, as well \r// as insertion of a blank line for the missing word format.\r//\r// Multiple Choice / Missing Word\r//     Who's buried in Grant's tomb?{~Grant ~Jefferson =no one}\r//     Grant is {~buried =entombed ~living} in Grant's tomb.\r// True-False:\r//     Grant is buried in Grant's tomb.{FALSE}\r// Short-Answer.\r//     Who's buried in Grant's tomb?{=no one =nobody}\r// Numerical\r//     When was Ulysses S. Grant born?{#1922:5}\r//\r// Comment lines start with a double backslash (//). \r// Optional question names are enclosed in double colon(::). \r// Answer feedback is indicated with hash mark (#).\r// Percentage answer weights immediately follow the tilde (for\r// multiple choice) or equal sign (for short answer and numerical),\r// and are enclosed in percent signs (% %). Below are more\r// complicated examples with various options and formatting styles.\r// \r//     ::Grant's Tomb::Grant is {\r//         ~buried#No one is buried there.\r//         =entombed#Right answer!\r//         ~living#We hope not!\r//     } in Grant's tomb.\r//\r//     Difficult multiple choice question.{\r//         ~wrong answer           #comment on wrong answer\r//         ~%50%half credit answer #comment on answer\r//         =full credit answer     #well done!}\r//\r//     ::Jesus' hometown (Short answer ex.):: Jesus Christ was from {\r//         =Nazareth#Yes! That's right!\r//         =%75%Nazereth#Right, but misspelled.\r//         =%25%Bethlehem#He was born here, but not raised here.\r//     }.\r//\r//     //this inline comment will be ignored by the filter\r//     ::Numerical example::\r//     When was Ulysses S. Grant born? {#\r//         =1922:0      #Correct! 100% credit\r//         =%50%1922:2  #He was born in 1922.\r//                       You get 50% credit for being close.\r//      }\r// \r// This filter was written through the collaboration of numerous \r// members of the Moodle community. It was originally based on \r// the missingword format, which included code from Thomas Robb\r// and others. Paul Tsuchido Shew wrote this filter in December 2003.\r//////////////////////////////////////////////////////////////////////////\r// Based on default.php, included by ../import.php\r\rclass quiz_file_format extends quiz_default_format {\r\r    function answerweightparser(&$answer) {\r        $answer = substr($answer, 1);                        // removes initial %\r        $end_position  = strpos($answer, "%");\r        $answer_weight = substr($answer, 0, $end_position);  // gets weight as integer\r        $answer_weight = $answer_weight/100;                 // converts to percent\r        $answer = substr($answer, $end_position+1);          // removes comment from answer\r        return $answer_weight;\r    }\r\r\r    function commentparser(&$answer) {\r        if (strpos($answer,"#") > 0){\r            $hashpos = strpos($answer,"#");\r            $comment = addslashes(substr($answer, $hashpos+1));\r            $answer  = substr($answer, 0, $hashpos);\r        } else {\r            $comment = " ";\r        }\r        return $comment;\r    }\r    \r\r    function readquestion($lines) {\r    // Given an array of lines known to define a question in this format, this function\r    // converts it into a question object suitable for processing and insertion into Moodle.\r\r        $question = NULL;\r        $comment = NULL;\r        define("GIFT_ANSWERWEIGHT_REGEX", "^%\-*([0-9]{1,2})\.?([0-9]*)%");        \r\r        // REMOVED COMMENTED LINES and IMPLODE\r        foreach ($lines as $key => $line) {\r           $line = trim($line);\r           if (substr($line, 0, 2) == "//") {\r                // echo "Commented line removed.<br />";\r                $lines[$key] = " ";\r                }\r        }\r\r        $text = trim(implode(" ", $lines));\r\r        if ($text == "") {\r            // echo "<p>Empty line.</p>";\r            return false;\r        }\r\r        // QUESTION NAME parser\r        if (substr($text, 0, 2) == "::") {\r            $text = substr($text, 2);\r\r            $namefinish = strpos($text, "::");\r            if ($namefinish === false) {\r                $question->name = false;\r                // name will be assigned after processing question text below\r             } else {\r                $question->name = addslashes(trim(substr($text, 0, $namefinish)));\r                $text = trim(substr($text, $namefinish+2)); // Remove name from text\r            }\r        } else {\r            $question->name = false;\r        }\r\r\r        // FIND ANSWER section\r        $answerstart = strpos($text, "{");\r        if ($answerstart === false) {\r            if ($this->displayerrors) {\r                echo "<P>$text<P>Could not find a {";\r            }\r            return false;\r        }\r\r        $answerfinish = strpos($text, "}");\r        if ($answerfinish === false) {\r            if ($this->displayerrors) {\r                echo "<P>$text<P>Could not find a }";\r            }\r            return false;\r        }\r\r        $answerlength = $answerfinish - $answerstart;\r        $answertext = trim(substr($text, $answerstart + 1, $answerlength - 1));\r\r        // Format QUESTION TEXT without answer, inserting "_____" as necessary\r        if (substr($text, -1) == "}") {\r            // no blank line if answers follow question, outside of closing punctuation\r            $question->questiontext = addslashes(trim(substr_replace($text, "", $answerstart, $answerlength+1)));\r        } else {\r            // inserts blank line for missing word format\r            $question->questiontext = addslashes(trim(substr_replace($text, "_____", $answerstart, $answerlength+1)));\r        }\r\r        // set question name if not already set\r        if ($question->name === false) {\r            $question->name = $question->questiontext;\r            }\r\r\r         // determine QUESTION TYPE\r        $question->qtype = NULL;\r\r        if ($answertext{0} == "#"){\r            $question->qtype = NUMERICAL;\r\r        } elseif (strstr($answertext, "~") !== false)  {\r            // only Multiplechoice questions contain tilde ~\r            $question->qtype = MULTICHOICE;\r    \r        } else { // either TRUEFALSE or SHORTANSWER\r    \r            // TRUEFALSE question check\r            $truefalse_check = $answertext;\r            if (strpos($answertext,"#") > 0){ \r                // strip comments to check for TrueFalse question\r                $truefalse_check = trim(substr($answertext, 0, strpos($answertext,"#")));\r            }\r\r            $valid_tf_answers = array("T", "TRUE", "F", "FALSE");\r            if (in_array($truefalse_check, $valid_tf_answers)) {\r                $question->qtype = TRUEFALSE;\r\r            } else { // Must be SHORTANSWER\r                    $question->qtype = SHORTANSWER;\r            }\r        }\r\r        if (!isset($question->qtype)) {\r            if ($this->displayerrors) {\r                echo "<P>$text<P>Question type not set.";\r                }\r            return false;\r        }\r\r        switch ($question->qtype) {\r            case MULTICHOICE:\r                if (strpos($answertext,"=") === false) {\r                    $question->single = 0;   // multiple answers are enabled if no single answer is 100% correct                        \r                } else {\r                    $question->single = 1;   // only one answer allowed (the default)\r                }\r\r                $answertext = str_replace("=", "~=", $answertext);\r                $answers = explode("~", $answertext);\r                if (isset($answers[0])) {\r                    $answers[0] = trim($answers[0]);\r                }\r                if (empty($answers[0])) {\r                    array_shift($answers);\r                }\r    \r                $countanswers = count($answers);\r                if ($countanswers < 2) {\r                    if ($this->displayerrors) {\r                        echo "<P>$text<P>Found tilde for multiple choice, \r                            but too few answers for Multiple Choice.<br />\r                            Found <u>$countanswers</u> answers in answertext.";\r                    }\r                    return false;\r                    break;\r                }\r    \r                foreach ($answers as $key => $answer) {\r                    $answer = trim($answer);\r\r                    // determine answer weight\r                    if ($answer[0] == "=") {\r                        $answer_weight = 1;\r                        $answer = substr($answer, 1);\r    \r                    } elseif (ereg(GIFT_ANSWERWEIGHT_REGEX, $answer)) {    // check for properly formatted answer weight\r                        $answer_weight = $this->answerweightparser($answer);\r                    \r                    } else {     //default, i.e., wrong anwer\r                        $answer_weight = 0;\r                    }\r                    $question->fraction[$key] = $answer_weight;\r                    $question->feedback[$key] = $this->commentparser($answer); // commentparser also removes comment from $answer\r                    $question->answer[$key]   = addslashes($answer);    \r                }  // end foreach answer\r    \r                $question->defaultgrade = 1;\r                $question->image = "";   // No images with this format\r                return $question;\r                break;\r            \r            case TRUEFALSE:\r                $answer = $answertext;\r                $comment = $this->commentparser($answer); // commentparser also removes comment from $answer\r\r                if ($answer == "T" OR $answer == "TRUE") {\r                    $question->answer = 1;\r                    $question->feedbackfalse = $comment; //feedback if answer is wrong\r                } else {\r                    $question->answer = 0;\r                    $question->feedbacktrue = $comment; //feedback if answer is wrong\r                }\r                $question->defaultgrade = 1;\r                $question->image = "";   // No images with this format\r                return $question;\r                break;\r                \r            case SHORTANSWER:\r                // SHORTANSWER Question\r                $answers = explode("=", $answertext);\r                if (isset($answers[0])) {\r                    $answers[0] = trim($answers[0]);\r                }\r                if (empty($answers[0])) {\r                    array_shift($answers);\r                }\r    \r                if (count($answers) == 0) {\r                    // invalid question\r                    if ($this->displayerrors) {\r                        echo "<P>$text<P>Found equals=, but no answers in answertext";\r                    }\r                    return false;\r                    break;\r                }\r\r                foreach ($answers as $key => $answer) {\r                    $answer = trim($answer);\r\r                    // Answer Weight\r                    if (ereg(GIFT_ANSWERWEIGHT_REGEX, $answer)) {    // check for properly formatted answer weight\r                        $answer_weight = $this->answerweightparser($answer);\r                    } else {     //default, i.e., full-credit anwer\r                        $answer_weight = 1;\r                    }\r                    $question->fraction[$key] = $answer_weight;\r                    $question->feedback[$key] = $this->commentparser($answer); //commentparser also removes comment from $answer\r                    $question->answer[$key]   = addslashes($answer);\r                }     // end foreach\r\r                $question->usecase = 0;  // Ignore case\r                $question->defaultgrade = 1;\r                $question->image = "";   // No images with this format\r                return $question;\r                break;\r\r            case NUMERICAL:\r                // Note similarities to ShortAnswer\r                $answertext = substr($answertext, 1); // remove leading "#"\r\r                $answers = explode("=", $answertext);\r                if (isset($answers[0])) {\r                    $answers[0] = trim($answers[0]);\r                }\r                if (empty($answers[0])) {\r                    array_shift($answers);\r                }\r    \r                if (count($answers) == 0) {\r                    // invalid question\r                    if ($this->displayerrors) {\r                        echo "<P>$text<P>No answers found in answertext (Numerical answer)";\r                    }\r                    return false;\r                    break;\r                }\r\r                foreach ($answers as $key => $answer) {\r                    $answer = trim($answer);\r\r                    // Answer weight\r                    if (ereg(GIFT_ANSWERWEIGHT_REGEX, $answer)) {    // check for properly formatted answer weight\r                        $answer_weight = $this->answerweightparser($answer);\r                    } else {     //default, i.e., full-credit anwer\r                        $answer_weight = 1;\r                    }\r                    $question->fraction[$key] = $answer_weight;\r                    $question->feedback[$key] = $this->commentparser($answer); //commentparser also removes comment from $answer\r\r                    //Calculate Answer and Min/Max values\r                    if (strpos($answer,"..") > 0) { // optional [min]..[max] format\r                        $marker                 = strpos($answer,"..");\r                        $question->max[$key]    = trim(substr($answer, $marker+2));\r                        $question->min[$key]    = trim(substr($answer, 0, $marker));\r                        $question->answer[$key] = ($question->max[$key] + $question->min[$key])/2;\r\r                    } elseif (strpos($answer,":") > 0){ // standard [answer]:[errormargin] format\r                        $marker                 = strpos($answer,":");\r                        $errormargin            = trim(substr($answer, $marker+1));\r                        $question->answer[$key] = trim(substr($answer, 0, $marker));\r                        $question->max[$key]    = $question->answer[$key] + $errormargin;\r                        $question->min[$key]    = $question->answer[$key] - $errormargin;\r\r                    } else { // only one valid answer (zero errormargin)\r                        $errormargin = 0;\r                        $question->answer[$key] = trim($answer);\r                        $question->max[$key]    = $question->answer[$key] + $errormargin;\r                        $question->min[$key]    = $question->answer[$key] - $errormargin;\r                    }\r    \r                    if (!is_numeric($question->answer[$key]) \r                     OR !is_numeric($question->max[$key])\r                     OR !is_numeric($question->max[$key])) {\r                        if ($this->displayerrors) {\r                            echo "<P>$text<P>For numerical questions, answer must be numbers.\r                                <P>Answer: <u>$answer</u><P>ErrorMargin: <u>$errormargin</u> .";\r                        }\r                        return false;\r                        break;\r                    }\r\r                }     // end foreach\r\r                $question->defaultgrade = 1;\r                $question->image = "";   // No images with this format\r                return $question;\r                break;\r\r                default:\r                if ($this->displayerrors) {\r                    echo "<P>$text<P> No valid question type. Error in switch(question->qtype)";\r                }\r                return false;\r                break;                \r        \r        } // end switch ($question->qtype)\r\r    }    // end function readquestion($lines)\r}\r\r?>\r
\ No newline at end of file