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