librarian integration with IOFile, pulling data from slowniczek
[librarian.git] / librarian / pyhtml.py
index db40909..88e1194 100644 (file)
@@ -4,16 +4,17 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from lxml import etree
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from lxml import etree
-from librarian import OutputFile, RDFNS, DCNS
+from librarian import IOFile, RDFNS, DCNS, Format
 from xmlutils import Xmill, tag, tagged, ifoption
 from librarian import functions
 import re
 import random
 
 
 from xmlutils import Xmill, tag, tagged, ifoption
 from librarian import functions
 import re
 import random
 
 
+
 class EduModule(Xmill):
 class EduModule(Xmill):
-    def __init__(self, *args):
-        super(EduModule, self).__init__(*args)
+    def __init__(self, options=None):
+        super(EduModule, self).__init__(options)
         self.activity_counter = 0
         self.register_text_filter(lambda t: functions.substitute_entities(None, t))
 
         self.activity_counter = 0
         self.register_text_filter(lambda t: functions.substitute_entities(None, t))
 
@@ -43,7 +44,7 @@ class EduModule(Xmill):
             'activity': True,
             'activity_counter': self.activity_counter
             }
             'activity': True,
             'activity_counter': self.activity_counter
             }
-        submill = EduModule()
+        submill = EduModule(self.options)
 
         opis = submill.generate(element.xpath('opis')[0])
 
 
         opis = submill.generate(element.xpath('opis')[0])
 
@@ -92,7 +93,7 @@ class EduModule(Xmill):
         return
 
     def handle_cwiczenie(self, element):
         return
 
     def handle_cwiczenie(self, element):
-        excercise_handlers = {
+        exercise_handlers = {
             'wybor': Wybor,
             'uporzadkuj': Uporzadkuj,
             'luki': Luki,
             'wybor': Wybor,
             'uporzadkuj': Uporzadkuj,
             'luki': Luki,
@@ -102,16 +103,20 @@ class EduModule(Xmill):
             }
 
         typ = element.attrib['typ']
             }
 
         typ = element.attrib['typ']
-        handler = excercise_handlers[typ](self.options)
+        handler = exercise_handlers[typ](self.options)
         return handler.generate(element)
 
     # Lists
     def handle_lista(self, element, attrs={}):
         ltype = element.attrib.get('typ', 'punkt')
         if ltype == 'slowniczek':
         return handler.generate(element)
 
     # Lists
     def handle_lista(self, element, attrs={}):
         ltype = element.attrib.get('typ', 'punkt')
         if ltype == 'slowniczek':
-            self.options = {'slowniczek': True}
+            surl = element.attrib.get('href', None)
+            sxml = None
+            if surl:
+                sxml = etree.fromstring(self.provider.by_uri(surl).get_string())
+            self.options = {'slowniczek': True, 'slowniczek_xml': sxml }
             return '<div class="slowniczek">', '</div>'
             return '<div class="slowniczek">', '</div>'
-### robie teraz punkty wyboru
+
         listtag = {'num': 'ol',
                'punkt': 'ul',
                'alfa': 'ul',
         listtag = {'num': 'ol',
                'punkt': 'ul',
                'alfa': 'ul',
@@ -131,6 +136,25 @@ class EduModule(Xmill):
         else:
             return '<li>', '</li>'
 
         else:
             return '<li>', '</li>'
 
+    def handle_definiendum(self, element):
+        nxt = element.getnext()
+        definiens_s = ''
+
+        # let's pull definiens from another document
+        if self.options['slowniczek_xml'] and (not nxt or nxt.tag != 'definiens'):
+            sxml = self.options['slowniczek_xml']
+            defloc = sxml.xpath("//definiendum[content()='%s']" % element.text)
+            if defloc:
+                definiens = defloc.getnext()
+                if definiens.tag == 'definiens':
+                    subgen = EduModule(self.options)
+                    definiens_s = subgen.generate(definiens)
+
+        return u"<dt>", u"</dt>" + definiens_s
+
+    def handle_definiens(self, element):
+        return u"<dd>", u"</dd>"
+
 
     def handle_podpis(self, element):
         return u"""<div class="caption">""", u"</div>"
 
     def handle_podpis(self, element):
         return u"""<div class="caption">""", u"</div>"
@@ -151,22 +175,31 @@ class EduModule(Xmill):
         # ustal w opcjach  rzeczy :D
         return
 
         # ustal w opcjach  rzeczy :D
         return
 
+    def handle_link(self, element):
+        if 'material' in element.attrib:
+            formats = re.split(r"[, ]+", element.attrib['format'])
+            fmt_links = []
+            for f in formats:
+                fmt_links.append(u'<a href="%s">%s</a>' % (self.options['urlmapper'].url_for_material(element.attrib['material'], f), f.upper()))
+
+            return u"", u' (%s)' % u' '.join(fmt_links)
+
 
 
-class Excercise(EduModule):
+class Exercise(EduModule):
     def __init__(self, *args, **kw):
         self.question_counter = 0
     def __init__(self, *args, **kw):
         self.question_counter = 0
-        super(Excercise, self).__init__(*args, **kw)
+        super(Exercise, self).__init__(*args, **kw)
 
     def handle_rozw_kom(self, element):
         return u"""<div style="display:none" class="comment">""", u"""</div>"""
 
     def handle_cwiczenie(self, element):
 
     def handle_rozw_kom(self, element):
         return u"""<div style="display:none" class="comment">""", u"""</div>"""
 
     def handle_cwiczenie(self, element):
-        self.options = {'excercise': element.attrib['typ']}
+        self.options = {'exercise': element.attrib['typ']}
         self.question_counter = 0
         self.piece_counter = 0
 
         pre = u"""
         self.question_counter = 0
         self.piece_counter = 0
 
         pre = u"""
-<div class="excercise %(typ)s" data-type="%(typ)s">
+<div class="exercise %(typ)s" data-type="%(typ)s">
 <form action="#" method="POST">
 """ % element.attrib
         post = u"""
 <form action="#" method="POST">
 """ % element.attrib
         post = u"""
@@ -211,7 +244,7 @@ class Excercise(EduModule):
             "</div>"
 
 
             "</div>"
 
 
-class Wybor(Excercise):
+class Wybor(Exercise):
     def handle_cwiczenie(self, element):
         pre, post = super(Wybor, self).handle_cwiczenie(element)
         is_single_choice = True
     def handle_cwiczenie(self, element):
         pre, post = super(Wybor, self).handle_cwiczenie(element)
         is_single_choice = True
@@ -224,7 +257,7 @@ class Wybor(Excercise):
         return pre, post
 
     def handle_punkt(self, element):
         return pre, post
 
     def handle_punkt(self, element):
-        if self.options['excercise'] and element.attrib.get('nazwa', None):
+        if self.options['exercise'] and element.attrib.get('nazwa', None):
             qc = self.question_counter
             self.piece_counter += 1
             no = self.piece_counter
             qc = self.question_counter
             self.piece_counter += 1
             no = self.piece_counter
@@ -247,7 +280,7 @@ class Wybor(Excercise):
             return super(Wybor, self).handle_punkt(element)
 
 
             return super(Wybor, self).handle_punkt(element)
 
 
-class Uporzadkuj(Excercise):
+class Uporzadkuj(Exercise):
     def handle_pytanie(self, element):
         """
 Overrides the returned content default handle_pytanie
     def handle_pytanie(self, element):
         """
 Overrides the returned content default handle_pytanie
@@ -266,7 +299,7 @@ Overrides the returned content default handle_pytanie
             "</li>"
 
 
             "</li>"
 
 
-class Luki(Excercise):
+class Luki(Exercise):
     def find_pieces(self, question):
         return question.xpath("//luka")
 
     def find_pieces(self, question):
         return question.xpath("//luka")
 
@@ -312,7 +345,7 @@ class Zastap(Luki):
             % self.piece_counter, '</span>'
 
 
             % self.piece_counter, '</span>'
 
 
-class Przyporzadkuj(Excercise):
+class Przyporzadkuj(Exercise):
     def handle_pytanie(self, element):
         pre, post = super(Przyporzadkuj, self).handle_pytanie(element)
         minimum = element.attrib.get("min", None)
     def handle_pytanie(self, element):
         pre, post = super(Przyporzadkuj, self).handle_pytanie(element)
         minimum = element.attrib.get("min", None)
@@ -357,7 +390,7 @@ class Przyporzadkuj(Excercise):
             return super(Przyporzadkuj, self).handle_punkt(element)
 
 
             return super(Przyporzadkuj, self).handle_punkt(element)
 
 
-class PrawdaFalsz(Excercise):
+class PrawdaFalsz(Exercise):
     def handle_punkt(self, element):
         if 'rozw' in element.attrib:
             return u'''<li data-solution="%s" class="question-piece">
     def handle_punkt(self, element):
         if 'rozw' in element.attrib:
             return u'''<li data-solution="%s" class="question-piece">
@@ -369,6 +402,24 @@ class PrawdaFalsz(Excercise):
             return super(PrawdaFalsz, self).handle_punkt(element)
 
 
             return super(PrawdaFalsz, self).handle_punkt(element)
 
 
+class EduModuleFormat(Format):
+    def __init__(self, wldoc, **kwargs):
+        super(EduModuleFormat, self).__init__(wldoc, **kwargs)
+
+    def build(self):
+        edumod = EduModule({'provider': self.wldoc.provider, 'urlmapper': self})
+
+        html = edumod.generate(self.wldoc.edoc.getroot())
+
+        return IOFile.from_string(html.encode('utf-8'))
+
+    def url_for_material(self, slug, fmt=None):
+        # No briliant idea for an API here.
+        if fmt:
+            return "%s.%s" % (slug, fmt)
+        return slug
+
+
 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.
 
@@ -376,8 +427,5 @@ def transform(wldoc, stylesheet='edumed', options=None, flags=None):
     otherwise returns True if file has been written,False if it hasn't.
     File won't be written if it has no content.
     """
     otherwise returns True if file has been written,False if it hasn't.
     File won't be written if it has no content.
     """
-    edumod = EduModule(options)
-#    from pdb import set_trace; set_trace()
-    html = edumod.generate(wldoc.edoc.getroot())
-
-    return OutputFile.from_string(html.encode('utf-8'))
+    edumodfor = EduModuleFormat(wldoc)
+    return edumodfor.build()