]> git.mjollnir.org Git - moodle.git/commitdiff
Converted to UNIX file type.
authorthetrinity <thetrinity>
Sat, 10 Jan 2004 09:50:14 +0000 (09:50 +0000)
committerthetrinity <thetrinity>
Sat, 10 Jan 2004 09:50:14 +0000 (09:50 +0000)
mod/quiz/format/gift/examples.txt
mod/quiz/format/gift/format.php

index fa95be6d2b823d81c8c3833ea87114a9effc7daa..3fcf7fe7793822d8f3739608f6f3422f2a7b216b 100644 (file)
@@ -1 +1,149 @@
-//  EXAMPLE QUESTIONS for the GIFT import filter\r//  by Paul Tsuchido Shew, January 2004.\r\r//-----------------------------------------//\r//        EXAMPLES FROM DESCRIPTION\r//-----------------------------------------//\r\rWho's buried in Grant's tomb?{~Grant ~Jefferson =no one}\r\rGrant is {~buried =entombed ~living} in Grant's tomb.\r\rGrant is buried in Grant's tomb.{FALSE}\r\rWho's buried in Grant's tomb?{=no one =nobody}\r\rWhen was Ulysses S. Grant born?{#1822:1}\r\r\r//-----------------------------------------//\r//       EXAMPLES FROM DOCUMENTATION\r//-----------------------------------------//\r\r// ===Multiple Choice===\r\rWho's buried in Grant's tomb?{~Grant ~Jefferson =no one}\r\rGrant is {~buried =entombed ~living} in Grant's tomb.\r\rThe American holiday of Thanksgiving is celebrated on the {\r    ~second\r    ~third\r    =fourth\r} Thursday of November.\r\rJapanese characters originally came from what country? {\r    ~India\r    =China\r    ~Korea\r    ~Egypt}\r\r// ===Short Answer===\r\rWho's buried in Grant's tomb?{=no one =nobody}\r\rTwo plus two equals {=four =4}.\r\r// ===True-False===\r\rGrant is buried in Grant's tomb.{F}\r\rThe sun rises in the east.{T}\r\r// ===Numerical===\r\rWhen was Ulysses S. Grant born? {#1822}\r\rWhat is the value of pi (to 3 decimal places)? {#3.1415:0.0005}.\r\rWhat is the value of pi (to 3 decimal places)? {#3.141..3.142}.\r\rWhen was Ulysses S. Grant born? {#\r    =1822:0\r    =%50%1822:2}\r\r// OPTIONS \r\r// ===Inline Comments===\r\r// Subheading: Numerical questions below\rWhat's 2 plus 2? {#4}\r\r\r// ===Question Name===\r\r::Kanji Origins::Japanese characters originally\rcame from what country? {=China}\r\r::Thanksgiving Date::The American holiday of Thanksgiving is \rcelebrated on the {~second ~third =fourth} Thursday of November.\r\r// ===Feedback===\r\rWhat's the answer to this multiple-choice question?{\r~wrong answer#feedback comment on the wrong answer\r~another wrong answer#feedback comment on this wrong answer\r=right answer#Very good!}\r    \rWho's buried in Grant's tomb?{\r=no one#excellent answer!\r=nobody#excellent answer!}\r\r// ===Percentage Answer Weights===\rGrant is buried in Grant's tomb.{FALSE#No one is buried in Grant's tomb.}\r\rDifficult question.{~wrong answer ~%50%half credit answer =full credit answer}\r         \r::Jesus' hometown::Jesus Christ was from {\r    ~Jerusalem#This was an important city, but the wrong answer.\r    ~%25%Bethlehem#He was born here, but not raised here.\r    ~%50%Galilee#You need to be more specific.\r    =Nazareth#Yes! That's right!}.\r    \r::Jesus' hometown:: 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// ===Multiple Answers===\r\rWhat two people are entombed in Grant's tomb? {\r  ~No one\r        ~%50%Grant\r     ~%50%Grant's wife\r      ~Grant's father }\r\rWhat two people are entombed in Grant's tomb? {\r     ~%-50%No one\r   ~%50%Grant\r     ~%50%Grant's wife\r      ~%-50%Grant's father }\r\r//-----------------------------------------//\r//     EXAMPLES FROM gift/format.php\r//-----------------------------------------//\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\rDifficult 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 comment will be ignored by the filter\r::Numerical example::\rWhen was Ulysses S. Grant born? {#\r     =1822:0      #Correct! 100% credit\r     =%50%1822:2  #He was born in 1822.\r                  You get 50% credit for being close.\r}
\ No newline at end of file
+//  EXAMPLE QUESTIONS for the GIFT import filter
+//  by Paul Tsuchido Shew, January 2004.
+
+//-----------------------------------------//
+//        EXAMPLES FROM DESCRIPTION
+//-----------------------------------------//
+
+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?{#1822:1}
+
+
+//-----------------------------------------//
+//       EXAMPLES FROM DOCUMENTATION
+//-----------------------------------------//
+
+// ===Multiple Choice===
+
+Who's buried in Grant's tomb?{~Grant ~Jefferson =no one}
+
+Grant is {~buried =entombed ~living} in Grant's tomb.
+
+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}
+
+// ===Short Answer===
+
+Who's buried in Grant's tomb?{=no one =nobody}
+
+Two plus two equals {=four =4}.
+
+// ===True-False===
+
+Grant is buried in Grant's tomb.{F}
+
+The sun rises in the east.{T}
+
+// ===Numerical===
+
+When was Ulysses S. Grant born? {#1822}
+
+What is the value of pi (to 3 decimal places)? {#3.1415:0.0005}.
+
+What is the value of pi (to 3 decimal places)? {#3.141..3.142}.
+
+When was Ulysses S. Grant born? {#
+    =1822:0
+    =%50%1822:2}
+
+// OPTIONS 
+
+// ===Inline Comments===
+
+// Subheading: Numerical questions below
+What's 2 plus 2? {#4}
+
+
+// ===Question Name===
+
+::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.
+
+// ===Feedback===
+
+What's the answer to this multiple-choice question?{
+~wrong answer#feedback comment on the wrong answer
+~another wrong answer#feedback comment on this wrong answer
+=right answer#Very good!}
+    
+Who's buried in Grant's tomb?{
+=no one#excellent answer!
+=nobody#excellent answer!}
+
+// ===Percentage Answer Weights===
+Grant is buried in Grant's tomb.{FALSE#No one is buried in Grant's tomb.}
+
+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.}
+
+// ===Multiple Answers===
+
+What two people are entombed in Grant's tomb? {
+       ~No one
+       ~%50%Grant
+       ~%50%Grant's wife
+       ~Grant's father }
+
+What two people are entombed in Grant's tomb? {
+       ~%-50%No one
+       ~%50%Grant
+       ~%50%Grant's wife
+       ~%-50%Grant's father }
+
+//-----------------------------------------//
+//     EXAMPLES FROM gift/format.php
+//-----------------------------------------//
+
+::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.
+}.
+
+//this comment will be ignored by the filter
+::Numerical example::
+When was Ulysses S. Grant born? {#
+     =1822:0      #Correct! 100% credit
+     =%50%1822:2  #He was born in 1822.
+                  You get 50% credit for being close.
+}
\ No newline at end of file
index 862fbd13ead2118a76f0d27ba564764b06f0efb3..ccde563c790b8aad242ed683c9c1fc512daa068a 100755 (executable)
@@ -1 +1,387 @@
-<?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?{#1822: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//         =1822:0      #Correct! 100% credit\r//         =%50%1982:2  #He was born in 1822.\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
+<?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?{#1822:5}
+//
+// Comment lines start with a double backslash (//). 
+// 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.
+//     }.
+//
+//     //this inline comment will be ignored by the filter
+//     ::Numerical example::
+//     When was Ulysses S. Grant born? {#
+//         =1822:0      #Correct! 100% credit
+//         =%50%1982:2  #He was born in 1822.
+//                       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.
+//////////////////////////////////////////////////////////////////////////
+// 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
+        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]*)%");        
+
+        // REMOVED COMMENTED LINES and IMPLODE
+        foreach ($lines as $key => $line) {
+           $line = trim($line);
+           if (substr($line, 0, 2) == "//") {
+                // echo "Commented line removed.<br />";
+                $lines[$key] = " ";
+                }
+        }
+
+        $text = trim(implode(" ", $lines));
+
+        if ($text == "") {
+            // echo "<p>Empty line.</p>";
+            return false;
+        }
+
+        // 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:
+                if (strpos($answertext,"=") === false) {
+                    $question->single = 0;   // multiple answers are enabled if no single answer is 100% correct                        
+                } else {
+                    $question->single = 1;   // only one answer allowed (the default)
+                }
+
+                $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;
+                }
+    
+                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)
+}
+
+?>