Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/quizdata/_format_gift.py
diff options
context:
space:
mode:
Diffstat (limited to 'quizdata/_format_gift.py')
-rw-r--r--quizdata/_format_gift.py92
1 files changed, 65 insertions, 27 deletions
diff --git a/quizdata/_format_gift.py b/quizdata/_format_gift.py
index b88e51c..437bf16 100644
--- a/quizdata/_format_gift.py
+++ b/quizdata/_format_gift.py
@@ -2,42 +2,80 @@
Parsing and support functions for the Moodle GIFT format.
'''
from pyparsing import (Word, Literal, Optional, Group, OneOrMore,
- ParseException, Combine, restOfLine, printables,
- nums)
+ ParseException, Combine, restOfLine,
+ nums, StringEnd, ZeroOrMore, oneOf,
+ originalTextFor, CharsNotIn, NotAny,
+ ParserElement, printables, White,
+ FollowedBy)
-_special_chars = set(":/=~#{}->")
-_filt_printables = ''.join([ p for p in printables if p not in _special_chars ])
+__all__ = [ 'parse', 'question', 'questions' ]
-_text = OneOrMore(Word(_filt_printables))
-_number = Combine(Word(nums) + Optional("." + Optional(Word(nums))))
+ParserElement.enablePackrat()
+#ParserElement.setDefaultWhitespaceChars(" \t")
-_comment = Literal("//") + restOfLine
-_dcolon = Literal("::")
-_qtitle = _dcolon + _text + _dcolon
+comment = Literal("//") + restOfLine
+NL = Literal("\n").suppress()
-_correct_ans = Literal("=") + _text
-_wrong_ans = Literal("~") + _text
-_ans_explain = Literal("#") + _text
-_ans_tf = Literal("TRUE") | Literal("FALSE") | Literal("T") | Literal("F")
-_ans_match = Literal("=") + _text + Literal("->") + _text
+def kill_whitespace(s, l, t):
+ #print t.asList()[1:-1]
+ return [ ' '.join(t.asList()[1:-1]).strip() ]
-_ans_numeric = (Optional(Literal("="))
- + (_number + Optional( Literal(":") + _number)
- |_number + Literal("..") + _number)
- + Optional( _ans_explain ))
+def printables_except(chars):
+ l = list(printables)
+ for c in chars:
+ l.remove(c)
+ return ''.join(l)
-_answer = ( (( _correct_ans | _wrong_ans ) + Optional(_ans_explain))
- | _ans_tf | _ans_match )
+def restricted_text(allowed_chars):
+ return originalTextFor(
+ Optional(NL)
+ + OneOrMore((Word(allowed_chars)
+ + Optional(NL)))
+ ).setParseAction( kill_whitespace )
-question = (Optional(_qtitle) + _text
- + ("{" + OneOrMore(_answer) + "}" |
- "{#" + OneOrMore(_ans_numeric) + "}"))
-question.ignore(_comment)
+text = restricted_text(printables)
+qtext = restricted_text(printables_except("{"))
+ans_text = restricted_text(printables_except("=~#}->"))
+after_text = text + FollowedBy(NL+NL)
+title_text = restricted_text(printables_except(":"))
-questions = OneOrMore(question + Literal("\n\n"))
-questions.ignore(_comment)
+number = Combine(Word(nums) + Optional("." + Optional(Word(nums))))
+dcolon = Literal("::")
+qtitle = dcolon.suppress() + title_text + dcolon.suppress()
-def _parse_only(text):
+correct_ans = (Literal("=") + ans_text)
+wrong_ans = Literal("~") + ans_text
+ans_explain = Literal("#") + ans_text
+ans_tf = oneOf("T F TRUE FALSE")
+ans_match = Literal("=") + ans_text + Literal("->") + ans_text
+
+ans_numeric = Group(Optional(Literal("="))
+ + (number + Optional( Literal(":") + number)
+ ^number + Literal("..") + number)
+ + Optional( ans_explain ))
+
+answer = Group(( ( correct_ans ^ wrong_ans ^ ans_tf) + Optional(ans_explain))
+ ^ ans_match )
+
+answer_list = ((Literal("{").suppress()
+ + OneOrMore(answer)
+ + Literal("}").suppress())
+ ^
+ (Literal("{#").suppress()
+ + OneOrMore(ans_numeric)
+ + Literal("}").suppress()))
+
+question = ZeroOrMore(NL) + Group( Optional(qtitle)("title") +
+ qtext("text") +
+ answer_list("answers") +
+ Optional(after_text)("text_additional") )
+
+question.ignore(comment)
+
+questions = (question + ZeroOrMore(NL + NL + question))("questions") + StringEnd()
+questions.ignore(comment)
+
+def parse_only(text):
return questions.parseText(text)
def parse(text):