Przyporzadkuj -- minimum answers
[librarian.git] / librarian / pyhtml.py
index 3690724..4ef04bc 100644 (file)
@@ -6,24 +6,27 @@
 from lxml import etree
 from librarian import OutputFile, RDFNS, DCNS
 from xmlutils import Xmill, tag, tagged, ifoption
 from lxml import etree
 from librarian import OutputFile, RDFNS, DCNS
 from xmlutils import Xmill, tag, tagged, ifoption
+from librarian import functions
+import re
+import random
+
 
 class EduModule(Xmill):
     def __init__(self, *args):
         super(EduModule, self).__init__(*args)
         self.activity_counter = 0
 
 class EduModule(Xmill):
     def __init__(self, *args):
         super(EduModule, self).__init__(*args)
         self.activity_counter = 0
+        self.register_text_filter(lambda t: functions.substitute_entities(None, t))
 
     def handle_powiesc(self, element):
         return u"""
 <div class="module" id="book-text">
 
     def handle_powiesc(self, element):
         return u"""
 <div class="module" id="book-text">
- <span class="teacher-toggle">
+<!-- <span class="teacher-toggle">
   <input type="checkbox" name="teacher-toggle" id="teacher-toggle"/>
   <label for="teacher-toggle">Pokaż treść dla nauczyciela</label>
   <input type="checkbox" name="teacher-toggle" id="teacher-toggle"/>
   <label for="teacher-toggle">Pokaż treść dla nauczyciela</label>
- </span>
+ </span>-->
 
 """, u"</div>"
 
 
 """, u"</div>"
 
-
     handle_autor_utworu = tag("span", "author")
     handle_nazwa_utworu = tag("h1", "title")
     handle_dzielo_nadrzedne = tag("span", "collection")
     handle_autor_utworu = tag("span", "author")
     handle_nazwa_utworu = tag("h1", "title")
     handle_dzielo_nadrzedne = tag("span", "collection")
@@ -37,7 +40,7 @@ class EduModule(Xmill):
     def handle_aktywnosc(self, element):
         self.activity_counter += 1
         self.options = {
     def handle_aktywnosc(self, element):
         self.activity_counter += 1
         self.options = {
-            'activity': True, 
+            'activity': True,
             'activity_counter': self.activity_counter
             }
         submill = EduModule()
             'activity_counter': self.activity_counter
             }
         submill = EduModule()
@@ -61,7 +64,7 @@ class EduModule(Xmill):
 
         return u"""
 <div class="activity">
 
         return u"""
 <div class="activity">
- <div class="text">%(counter)d. 
+ <div class="text">%(counter)d.
   %(opis)s
   %(wskazowki)s
  </div>
   %(opis)s
   %(wskazowki)s
  </div>
@@ -76,27 +79,28 @@ class EduModule(Xmill):
 
     handle_opis = ifoption(activity=False)(tag('div', 'description'))
     handle_wskazowki = ifoption(activity=False)(tag('div', ('hints', 'teacher')))
 
     handle_opis = ifoption(activity=False)(tag('div', 'description'))
     handle_wskazowki = ifoption(activity=False)(tag('div', ('hints', 'teacher')))
-    
+
     @ifoption(activity=False)
     @tagged('div', 'materials')
     def handle_pomoce(self, _):
         return "Pomoce: ", ""
     @ifoption(activity=False)
     @tagged('div', 'materials')
     def handle_pomoce(self, _):
         return "Pomoce: ", ""
-    
+
     def handle_czas(self, *_):
         return
 
     def handle_forma(self, *_):
         return
     def handle_czas(self, *_):
         return
 
     def handle_forma(self, *_):
         return
-            
+
     def handle_cwiczenie(self, element):
         excercise_handlers = {
             'wybor': Wybor,
             'uporzadkuj': Uporzadkuj,
             'luki': Luki,
             'zastap': Zastap,
     def handle_cwiczenie(self, element):
         excercise_handlers = {
             'wybor': Wybor,
             'uporzadkuj': Uporzadkuj,
             'luki': Luki,
             'zastap': Zastap,
-            'przyporzadkuj': Przyporzadkuj
+            'przyporzadkuj': Przyporzadkuj,
+            'prawdafalsz': PrawdaFalsz
             }
             }
-        
+
         typ = element.attrib['typ']
         handler = excercise_handlers[typ](self.options)
         return handler.generate(element)
         typ = element.attrib['typ']
         handler = excercise_handlers[typ](self.options)
         return handler.generate(element)
@@ -108,17 +112,17 @@ class EduModule(Xmill):
             self.options = {'slowniczek': True}
             return '<div class="slowniczek">', '</div>'
 ### robie teraz punkty wyboru
             self.options = {'slowniczek': True}
             return '<div class="slowniczek">', '</div>'
 ### robie teraz punkty wyboru
-        listtag = {'num': 'ol', 
-               'punkt': 'ul', 
-               'alfa': 'ul', 
+        listtag = {'num': 'ol',
+               'punkt': 'ul',
+               'alfa': 'ul',
                'czytelnia': 'ul'}[ltype]
 
         classes = attrs.get('class', '')
         if classes: del attrs['class']
                'czytelnia': 'ul'}[ltype]
 
         classes = attrs.get('class', '')
         if classes: del attrs['class']
-            
+
         attrs_s = ' '.join(['%s="%s"' % kv for kv in attrs.items()])
         if attrs_s: attrs_s = ' ' + attrs_s
         attrs_s = ' '.join(['%s="%s"' % kv for kv in attrs.items()])
         if attrs_s: attrs_s = ' ' + attrs_s
-            
+
         return '<%s class="lista %s %s"%s>' % (listtag, ltype, classes, attrs_s), '</%s>' % listtag
 
     def handle_punkt(self, element):
         return '<%s class="lista %s %s"%s>' % (listtag, ltype, classes, attrs_s), '</%s>' % listtag
 
     def handle_punkt(self, element):
@@ -129,7 +133,7 @@ class EduModule(Xmill):
 
     def handle_rdf__RDF(self, _):
         # ustal w opcjach  rzeczy :D
 
     def handle_rdf__RDF(self, _):
         # ustal w opcjach  rzeczy :D
-        return 
+        return
 
 
 class Excercise(EduModule):
 
 
 class Excercise(EduModule):
@@ -154,6 +158,7 @@ class Excercise(EduModule):
 <span class="message"></span>
 <input type="button" class="check" value="sprawdź"/>
 <input type="button" class="solutions" value="pokaż rozwiązanie"/>
 <span class="message"></span>
 <input type="button" class="check" value="sprawdź"/>
 <input type="button" class="solutions" value="pokaż rozwiązanie"/>
+<input type="button" class="reset" value="reset"/>
 </div>
 </form>
 </div>
 </div>
 </form>
 </div>
@@ -164,22 +169,43 @@ class Excercise(EduModule):
             pre = pre + qpre
             post = qpost + post
         return pre, post
             pre = pre + qpre
             post = qpost + post
         return pre, post
+
     def handle_pytanie(self, element):
         """This will handle <cwiczenie> element, when there is no <pytanie>
         """
     def handle_pytanie(self, element):
         """This will handle <cwiczenie> element, when there is no <pytanie>
         """
+        add_class = ""
         self.question_counter += 1
         self.piece_counter = 0
         solution = element.attrib.get('rozw', None)
         if solution: solution_s = ' data-solution="%s"' % solution
         else: solution_s = ''
 
         self.question_counter += 1
         self.piece_counter = 0
         solution = element.attrib.get('rozw', None)
         if solution: solution_s = ' data-solution="%s"' % solution
         else: solution_s = ''
 
-        return '<div class="question" data-no="%d" %s>' %\
-            (self.question_counter, solution_s), \
-    "</div>"
+        handles = element.attrib.get('uchwyty', None)
+        if handles:
+            add_class += ' handles handles-%s' % handles
+            self.options = {'handles': handles}
+
+        minimum = element.attrib.get('min', None)
+        if minimum: minimum_s = ' data-minimum="%d"' % int(minimum)
+        else: minimum_s = ''
+
+        return '<div class="question%s" data-no="%d" %s>' %\
+            (add_class, self.question_counter, solution_s + minimum_s), \
+            "</div>"
 
 
 class Wybor(Excercise):
 
 
 class Wybor(Excercise):
+    def handle_cwiczenie(self, element):
+        pre, post = super(Wybor, self).handle_cwiczenie(element)
+        is_single_choice = True
+        for p in element.xpath(".//pytanie"):
+            solutions = re.split(r"[, ]+", p.attrib['rozw'])
+            if len(solutions) != 1:
+                is_single_choice = False
+                break
+        self.options = {'single': is_single_choice}
+        return pre, post
+
     def handle_punkt(self, element):
         if self.options['excercise'] and element.attrib.get('nazwa', None):
             qc = self.question_counter
     def handle_punkt(self, element):
         if self.options['excercise'] and element.attrib.get('nazwa', None):
             qc = self.question_counter
@@ -187,9 +213,16 @@ class Wybor(Excercise):
             no = self.piece_counter
             eid = "q%(qc)d_%(no)d" % locals()
             aname = element.attrib.get('nazwa', None)
             no = self.piece_counter
             eid = "q%(qc)d_%(no)d" % locals()
             aname = element.attrib.get('nazwa', None)
-            return u"""
+            if self.options['single']:
+                return u"""
 <li class="question-piece" data-qc="%(qc)d" data-no="%(no)d" data-name="%(aname)s">
 <li class="question-piece" data-qc="%(qc)d" data-no="%(no)d" data-name="%(aname)s">
-<input type="checkbox" name="" id="%(eid)s" />
+<input type="radio" name="q%(qc)d" id="%(eid)s" value="%(aname)s" />
+<label for="%(eid)s">
+                """ % locals(), u"</label></li>"
+            else:
+                return u"""
+<li class="question-piece" data-qc="%(qc)d" data-no="%(no)d" data-name="%(aname)s">
+<input type="checkbox" name="%(eid)s" id="%(eid)s" />
 <label for="%(eid)s">
 """ % locals(), u"</label></li>"
 
 <label for="%(eid)s">
 """ % locals(), u"</label></li>"
 
@@ -217,46 +250,108 @@ Overrides the returned content default handle_pytanie
 
 
 class Luki(Excercise):
 
 
 class Luki(Excercise):
+    def find_pieces(self, question):
+        return question.xpath("//luka")
+
+    def solution_html(self, piece):
+        return piece.text + ''.join(
+            [etree.tostring(n, encoding=unicode)
+             for n in piece])
+
+    def handle_pytanie(self, element):
+        qpre, qpost = super(Luki, self).handle_pytanie(element)
+
+        luki = list(enumerate(self.find_pieces(element)))
+        luki_html = ""
+        i = 0
+        random.shuffle(luki)
+        for (i, luka) in luki:
+            i += 1
+            luka_html = self.solution_html(luka)
+            luki_html += u'<span class="draggable question-piece" data-no="%d">%s</span>' % (i, luka_html)
+        self.words_html = '<div class="words">%s</div>' % luki_html
+
+        return qpre, qpost
+
+    def handle_opis(self, element):
+        pre, post = super(Luki, self).handle_opis(element)
+        return pre, self.words_html + post
+
     def handle_luka(self, element):
     def handle_luka(self, element):
-        return '<input type="text" class="luka question-piece" data-solution="%s"></input>' % element.text
+        self.piece_counter += 1
+        return '<span class="placeholder" data-solution="%d"></span>' % self.piece_counter
+
 
 
+class Zastap(Luki):
+    def find_pieces(self, question):
+        return question.xpath("//zastap")
+
+    def solution_html(self, piece):
+        return piece.attrib['rozw']
 
 
-class Zastap(Excercise):
     def handle_zastap(self, element):
     def handle_zastap(self, element):
-        return '<span class="zastap question-piece" data-solution="%(rozw)s">' % element.attrib, '</span>'
+        self.piece_counter += 1
+        return '<span class="placeholder zastap question-piece" data-solution="%d">' \
+            % self.piece_counter, '</span>'
 
 
 class Przyporzadkuj(Excercise):
 
 
 class Przyporzadkuj(Excercise):
+    def handle_pytanie(self, element):
+        pre, post = super(Przyporzadkuj, self).handle_pytanie(element)
+        minimum = element.attrib.get("min", None)
+        if minimum:
+            self.options = {"min": int(minimum)}
+        return pre, post
+
     def handle_lista(self, lista):
     def handle_lista(self, lista):
-        print "in lista %s %s" % (lista.attrib, self.options)
         if 'nazwa' in lista.attrib:
             attrs = {
                 'data-name': lista.attrib['nazwa'],
                 'class': 'predicate'
         if 'nazwa' in lista.attrib:
             attrs = {
                 'data-name': lista.attrib['nazwa'],
                 'class': 'predicate'
-                }
+            }
             self.options = {'predicate': True}
         elif 'cel' in lista.attrib:
             attrs = {
                 'data-target': lista.attrib['cel'],
                 'class': 'subject'
             self.options = {'predicate': True}
         elif 'cel' in lista.attrib:
             attrs = {
                 'data-target': lista.attrib['cel'],
                 'class': 'subject'
-                }
-            self.options = {'subject': True}
+            }
+            self.options = {'subject': True, 'handles': 'uchwyty' in lista.attrib}
         else:
             attrs = {}
         pre, post = super(Przyporzadkuj, self).handle_lista(lista, attrs)
         return pre, post + '<br class="clr"/>'
 
     def handle_punkt(self, element):
         else:
             attrs = {}
         pre, post = super(Przyporzadkuj, self).handle_lista(lista, attrs)
         return pre, post + '<br class="clr"/>'
 
     def handle_punkt(self, element):
-        print "in punkt %s %s" % (element.attrib, self.options)
-
         if self.options['subject']:
         if self.options['subject']:
-            return '<li data-solution="%(rozw)s" class="question-piece draggable">' % element.attrib, '</li>'
+            self.piece_counter += 1
+            if self.options['handles']:
+                return '<li><span data-solution="%s" data-no="%s" class="question-piece draggable handle">%s</span>' % (element.attrib['rozw'], self.piece_counter, self.piece_counter), '</li>'
+            else:
+                return '<li data-solution="%s" data-no="%s" class="question-piece draggable">' % (element.attrib['rozw'], self.piece_counter), '</li>'
+
         elif self.options['predicate']:
         elif self.options['predicate']:
-            return '<li data-predicate="%(nazwa)s">' % element.attrib, '<ul class="subjects droppable"></ul></li>'
+            if self.options['min']:
+                placeholders = u'<li class="placeholder"/>' * self.options['min']
+            else:
+                placeholders = u'<li class="placeholder multiple"/>'
+            return '<li data-predicate="%(nazwa)s">' % element.attrib, '<ul class="subjects">' + placeholders + '</ul></li>'
+
         else:
             return super(Przyporzadkuj, self).handle_punkt(element)
 
 
         else:
             return super(Przyporzadkuj, self).handle_punkt(element)
 
 
+class PrawdaFalsz(Excercise):
+    def handle_punkt(self, element):
+        if 'rozw' in element.attrib:
+            return u'''<li data-solution="%s" class="question-piece">
+            <span class="buttons">
+            <a href="#" data-value="true" class="true">Prawda</a>
+            <a href="#" data-value="false" class="false">Fałsz</a>
+        </span>''' % {'prawda': 'true', 'falsz': 'false'}[element.attrib['rozw']], '</li>'
+        else:
+            return super(PrawdaFalsz, self).handle_punkt(element)
+
+
 def transform(wldoc, stylesheet='edumed', options=None, flags=None):
     """Transforms the WL document to XHTML.
 
 def transform(wldoc, stylesheet='edumed', options=None, flags=None):
     """Transforms the WL document to XHTML.