40d7777a68755aab877195006e6e51dd6fb870a0
[librarian.git] / src / librarian / builders / html.py
1 # coding: utf-8
2 from __future__ import unicode_literals
3
4 from lxml import etree
5 from librarian.html import add_anchors, add_table_of_contents, add_table_of_themes
6 from librarian import OutputFile
7
8
9 class HtmlBuilder:
10     file_extension = "html"
11     identifier = "html"
12
13     def __init__(self, image_location='https://wolnelektury.pl/media/book/pictures/marcos-historia-kolorow/'):
14         self.image_location = image_location
15
16         self.tree = text = etree.Element('div', **{'id': 'book-text'})
17         self.header = etree.SubElement(text, 'h1')
18
19         self.footnotes = etree.Element('div', id='footnotes')
20         self.footnote_counter = 0
21
22         self.nota_red = etree.Element('div', id='nota_red')
23
24         self.cursors = {
25             None: text,
26             'header': self.header,
27             'footnotes': self.footnotes,
28             'nota_red': self.nota_red,
29         }
30         self.current_cursors = [None]
31
32     @property
33     def cursor(self):
34         return self.cursors[self.current_cursors[-1]]
35
36     @cursor.setter
37     def cursor(self, value):
38         self.cursors[self.current_cursors[-1]] = value
39
40     def enter_fragment(self, fragment):
41         self.current_cursors.append(fragment)
42
43     def exit_fragment(self):
44         self.current_cursors.pop()
45
46     def create_fragment(self, name, element):
47         assert name not in self.cursors
48         self.cursors[name] = element
49
50     def forget_fragment(self, name):
51         del self.cursors[name]
52
53     def preprocess(self, document):
54         document._compat_assign_ordered_ids()
55         document._compat_assign_section_ids()
56
57     def build(self, document):
58         self.preprocess(document)
59         document.tree.getroot().html_build(self)
60         self.postprocess(document)
61
62         return OutputFile.from_bytes(
63             etree.tostring(
64                 self.tree,
65                 method='html',
66                 encoding='utf-8',
67                 pretty_print=True
68             )
69         )
70
71     def postprocess(self, document):
72         _ = document.tree.getroot().master.gettext
73
74         if document.meta.translators:
75             self.enter_fragment('header')
76             self.start_element('span', {'class': 'translator'})
77             self.push_text(_("translated by") + " ")
78             self.push_text(
79                 ", ".join(
80                     translator.readable()
81                     for translator in document.meta.translators
82                 )
83             )
84             self.exit_fragment()
85
86         add_anchors(self.tree)
87         if len(self.nota_red):
88             self.tree.append(self.nota_red)
89         add_table_of_themes(self.tree)
90         add_table_of_contents(self.tree)
91
92         if self.footnote_counter:
93             fnheader = etree.Element("h3")
94             fnheader.text = _("Footnotes")
95             self.footnotes.insert(0, fnheader)
96             self.tree.append(self.footnotes)
97
98     def start_element(self, tag, attrib=None):
99         self.cursor = etree.SubElement(
100             self.cursor,
101             tag,
102             **(attrib or {})
103         )
104
105     def end_element(self):
106         self.cursor = self.cursor.getparent()
107
108     def push_text(self, text):
109         if text == 'Między nami nic nie było':
110             print(self.cursors)
111             print(self.current_cursors)
112         cursor = self.cursor
113         if len(cursor):
114             cursor[-1].tail = (cursor[-1].tail or '') + text
115         else:
116             cursor.text = (cursor.text or '') + text
117
118
119 class StandaloneHtmlBuilder(HtmlBuilder):
120     def postprocess(self, document):
121         super(StandaloneHtmlBuilder, self).postprocess(document)
122
123         tree = etree.Element('html')
124         body = etree.SubElement(tree, 'body')
125         body.append(self.tree)
126         self.tree = tree
127
128         head = etree.Element('head')
129         tree.insert(0, head)
130
131
132         etree.SubElement(head, 'meta', charset='utf-8')
133         etree.SubElement(head, 'title').text = document.meta.title
134
135         etree.SubElement(
136             head,
137             'meta',
138             name="viewport",
139             content="width=device-width, initial-scale=1, maximum-scale=1"
140         )
141
142         etree.SubElement(
143             head,
144             'link',
145             href="https://static.wolnelektury.pl/css/compressed/book_text.css",
146             rel="stylesheet",
147             type="text/css",
148         )
149
150         etree.SubElement(
151             body, 'script',
152             src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"
153         )
154
155         etree.SubElement(
156             body,
157             "script",
158             src="http://malsup.github.io/min/jquery.cycle2.min.js"
159         )