excercises: uporzadkuj, zastap, luki
[librarian.git] / librarian / pyhtml.py
1 # -*- coding: utf-8 -*-
2 #
3 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
4 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
5 #
6 from lxml import etree
7 from librarian import OutputFile, RDFNS, DCNS
8 from xmlutils import Xmill, tag, tagged, ifoption
9  
10
11 class EduModule(Xmill):
12     def __init__(self, *args):
13         super(EduModule, self).__init__(*args)
14         self.activity_counter = 0
15
16
17
18 #     def handle_utwor(self, element):
19 #         v = {}
20 # #        from pdb import *; set_trace()
21 #         v['title'] = element.xpath('//dc:title/text()', namespaces={'dc':DCNS.uri})[0]
22 #         return u"""
23 # <!DOCTYPE html>
24 # <html>
25 # <head>
26 # <meta charset="utf-8"/>
27 # <title>%(title)s</title>
28 # <link rel="stylesheet" type="text/css" href="/media/static/edumed/edumed.css"/>
29 # <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
30 # <script src="/media/static/edumed/js/edumed.js"></script>
31 # </head>
32 # <body>
33 # """ % v, u"""
34 # </body>
35 # </html>
36 # """
37
38     
39     def handle_powiesc(self, element):
40         return u"""
41 <div class="module" id="book-text">
42  <span class="teacher-toggle">
43   <input type="checkbox" name="teacher-toggle" id="teacher-toggle"/>
44   <label for="teacher-toggle">Pokaż treść dla nauczyciela</label>
45  </span>
46
47 """, u"</div>"
48
49
50     handle_autor_utworu = tag("span", "author")
51     handle_nazwa_utworu = tag("h1", "title")
52     handle_dzielo_nadrzedne = tag("span", "collection")
53     handle_podtytul = tag("span", "subtitle")
54     handle_naglowek_akt = handle_naglowek_czesc = handle_srodtytul = tag("h2")
55     handle_naglowek_scena = handle_naglowek_rozdzial = tag('h3')
56     handle_naglowek_osoba = handle_naglowek_podrozdzial = tag('h4')
57     handle_akap = handle_akap_dialog = handle_akap_cd = tag('p', 'paragraph')
58     handle_strofa = tag('div', 'stanza')
59
60     def handle_aktywnosc(self, element):
61         self.activity_counter += 1
62         self.options = {
63             'activity': True, 
64             'activity_counter': self.activity_counter
65             }
66         submill = EduModule()
67
68         opis = submill.generate(element.xpath('opis')[0])
69
70         n = element.xpath('wskazowki')
71         if n: wskazowki = submill.generate(n[0])
72
73         else: wskazowki = ''
74         n = element.xpath('pomoce')
75
76         if n: pomoce = submill.generate(n[0])
77         else: pomoce = ''
78
79         forma = ''.join(element.xpath('forma/text()'))
80
81         czas = ''.join(element.xpath('czas/text()'))
82
83         counter = self.activity_counter
84
85         return u"""
86 <div class="activity">
87  <div class="text">%(counter)d. 
88   %(opis)s
89   %(wskazowki)s
90  </div>
91  <div class="info">
92   <p>Czas: %(czas)s min</p>
93   <p>Forma: %(forma)s</p>
94   %(pomoce)s
95  </div>
96  <div class="clearboth"></div>
97 </div>
98 """ % locals()
99
100     handle_opis = ifoption(activity=False)(tag('div', 'description'))
101     handle_wskazowki = ifoption(activity=False)(tag('div', ('hints', 'teacher')))
102     
103     @ifoption(activity=False)
104     @tagged('div', 'materials')
105     def handle_pomoce(self, _):
106         return "Pomoce: ", ""
107     
108     def handle_czas(self, *_):
109         return
110
111     def handle_forma(self, *_):
112         return
113             
114     def handle_cwiczenie(self, element):
115         excercise_handlers = {
116             'wybor': Wybor,
117             'uporzadkuj': Uporzadkuj,
118             'luki': Luki,
119             'zastap': Zastap,
120             }
121         
122         typ = element.attrib['typ']
123         handler = excercise_handlers[typ](self.options)
124         return handler.generate(element)
125
126     # Lists
127     def handle_lista(self, element, attrs={}):
128         ltype = element.attrib.get('typ', 'punkt')
129         if ltype == 'slowniczek':
130             self.options = {'slowniczek': True}
131             return '<div class="slowniczek">', '</div>'
132 ### robie teraz punkty wyboru
133         listtag = {'num': 'ol', 
134                'punkt': 'ul', 
135                'alfa': 'ul', 
136                'czytelnia': 'ul'}[ltype]
137
138         classes = attrs.get('class', '')
139         if classes: del attrs['class']
140             
141         attrs_s = ' '.join(['%s="%s"' % kv for kv in attrs.items()])
142         if attrs_s: attrs_s = ' ' + attrs_s
143             
144         return '<%s class="lista %s %s"%s>' % (listtag, ltype, classes, attrs_s), '</%s>' % listtag
145
146     def handle_punkt(self, element):
147         if self.options['slowniczek']:
148             return '<dl>', '</dl>'
149         else:
150             return '<li>', '</li>'
151
152     def handle_rdf__RDF(self, _):
153         # ustal w opcjach  rzeczy :D
154         return 
155
156
157 class Excercise(EduModule):
158     def __init__(self, *args, **kw):
159         self.question_counter = 0
160         super(Excercise, self).__init__(*args, **kw)
161
162     def handle_cwiczenie(self, element):
163         self.options = {'excercise': element.attrib['typ']}
164         self.question_counter = 0
165         self.piece_counter = 0
166
167         return u"""
168 <div class="excercise %(typ)s" data-type="%(typ)s">
169 <form action="#" method="POST">
170 """ % element.attrib, \
171 u"""
172 <div class="buttons">
173 <span class="message"></span>
174 <input type="button" class="check" value="sprawdź"/>
175 <input type="button" class="solutions" value="pokaż rozwiązanie"/>
176 </div>
177 </form>
178 </div>
179 """
180  
181     def handle_pytanie(self, element):
182         self.question_counter += 1
183         self.piece_counter = 0
184         solution = element.attrib.get('rozw', None)
185         if solution: solution_s = ' data-solution="%s"' % solution
186         else: solution_s = ''
187
188         return '<div class="question" data-no="%d" %s>' %\
189             (self.question_counter, solution_s), \
190     "</div>"    
191
192
193 class Wybor(Excercise):
194     def handle_punkt(self, element):
195         if self.options['excercise'] and element.attrib.get('nazwa', None):
196             qc = self.question_counter
197             self.piece_counter += 1
198             no = self.piece_counter
199             eid = "q%(qc)d_%(no)d" % locals()
200             return u"""
201 <li class="question-piece" data-qc="%(qc)d" data-no="%(no)d">
202 <input type="checkbox" name="" id="%(eid)s" />
203 <label for="%(eid)s">
204 """ % locals(), u"</label></li>"
205
206         else:
207             return super(Wybor, self).handle_punkt(element)
208
209
210 class Uporzadkuj(Excercise):
211     def handle_cwiczenie(self, element):
212         pre, post = super(Uporzadkuj, self).handle_cwiczenie(element)
213         order_items = element.xpath(".//punkt/@rozw")
214         import pdb
215         if order_items == []: pdb.set_trace()
216
217         return pre + u"""<div class="question" data-original="%s">""" % \
218             ','.join(order_items), \
219             u"""</div>""" + post
220     
221     def handle_punkt(self, element):
222         return """<li class="question-piece" data-pos="%(rozw)s"/>""" \
223             % element.attrib,\
224             "</li>"
225
226
227 class Luki(Excercise):
228     def handle_luka(self, element):
229         return '<input type="text" class="luka question-piece" data-solution="%s"></input>' % element.text
230
231
232
233 class Zastap(Excercise):
234     def handle_zastap(self, element):
235         return '<span class="zastap question-piece" data-solution="%(rozw)s">' % element.attrib, '</span>'
236
237
238 class Przyporzadkuj(Excercise):
239     def handle_lista(self, element):
240         if 'nazwa' in lista.attrib:
241             attrs = {
242                 'data-name': lista.attrib['nazwa'],
243                 'class': 'category'
244                 }
245         elif 'cel' in lista.attrib:
246             attrs = {
247                 'data-target': lista.attrib['cel'],
248                 'class': 'object'
249                 }
250         else:
251             attrs = {}
252         return super(Przyporzadkuj, self).handle_lista(element, attrs)  
253
254
255
256
257 def transform(wldoc, stylesheet='edumed', options=None, flags=None):
258     """Transforms the WL document to XHTML.
259
260     If output_filename is None, returns an XML,
261     otherwise returns True if file has been written,False if it hasn't.
262     File won't be written if it has no content.
263     """
264     
265     edumod = EduModule(options)
266 #    from pdb import set_trace; set_trace()
267     html = edumod.generate(wldoc.edoc.getroot())
268
269     return OutputFile.from_string(html.encode('utf-8'))