1 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
 
   2 # Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
 
   4 from urllib.request import urlopen
 
   6 from librarian.html import add_anchors, add_table_of_contents, add_table_of_themes
 
   7 from librarian import OutputFile
 
  11     file_extension = "html"
 
  17     no_externalities = False
 
  20     def __init__(self, base_url=None):
 
  21         self._base_url = base_url
 
  23         self.tree = text = etree.Element('div', **{'id': 'book-text'})
 
  24         self.header = etree.Element('h1')
 
  26         self.footnotes = etree.Element('div', id='footnotes')
 
  27         self.footnote_counter = 0
 
  29         self.nota_red = etree.Element('div', id='nota_red')
 
  33             'header': self.header,
 
  34             'footnotes': self.footnotes,
 
  35             'nota_red': self.nota_red,
 
  37         self.current_cursors = [text]
 
  41         if self._base_url is not None:
 
  44             return 'https://wolnelektury.pl/media/book/pictures/{}/'.format(self.document.meta.url.slug)
 
  48         return self.current_cursors[-1]
 
  50     def enter_fragment(self, fragment):
 
  51         cursor = self.cursors.get(fragment, self.cursor)
 
  52         self.current_cursors.append(cursor)
 
  54     def exit_fragment(self):
 
  55         self.current_cursors.pop()
 
  57     def create_fragment(self, name, element):
 
  58         assert name not in self.cursors
 
  59         self.cursors[name] = element
 
  61     def forget_fragment(self, name):
 
  62         del self.cursors[name]
 
  64     def preprocess(self, document):
 
  65         document._compat_assign_ordered_ids()
 
  66         document._compat_assign_section_ids()
 
  68     def build(self, document, **kwargs):
 
  69         self.document = document
 
  71         self.preprocess(document)
 
  72         document.tree.getroot().html_build(self)
 
  73         self.postprocess(document)
 
  77         return OutputFile.from_bytes(
 
  86     def postprocess(self, document):
 
  87         _ = document.tree.getroot().master.gettext
 
  89         if document.meta.translators:
 
  90             self.enter_fragment('header')
 
  91             self.start_element('span', {'class': 'translator'})
 
  92             self.push_text(_("translated by") + " ")
 
  96                     for translator in document.meta.translators
 
 102             self.tree.insert(0, self.header)
 
 104         if self.with_anchors:
 
 105             add_anchors(self.tree)
 
 106         if self.with_nota_red and len(self.nota_red):
 
 107             self.tree.append(self.nota_red)
 
 109             add_table_of_themes(self.tree)
 
 111             add_table_of_contents(self.tree)
 
 113         if self.footnote_counter:
 
 114             fnheader = etree.Element("h3")
 
 115             fnheader.text = _("Footnotes")
 
 116             self.footnotes.insert(0, fnheader)
 
 117             self.tree.append(self.footnotes)
 
 119     def start_element(self, tag, attrib=None):
 
 120         self.current_cursors.append(etree.SubElement(
 
 126     def end_element(self):
 
 127         self.current_cursors.pop()
 
 129     def push_text(self, text):
 
 132             cursor[-1].tail = (cursor[-1].tail or '') + text
 
 134             cursor.text = (cursor.text or '') + text
 
 137 class StandaloneHtmlBuilder(HtmlBuilder):
 
 138     css_url = "https://static.wolnelektury.pl/css/compressed/book_text.css"
 
 140     def postprocess(self, document):
 
 141         super(StandaloneHtmlBuilder, self).postprocess(document)
 
 143         tree = etree.Element('html')
 
 144         body = etree.SubElement(tree, 'body')
 
 145         body.append(self.tree)
 
 148         head = etree.Element('head')
 
 152         etree.SubElement(head, 'meta', charset='utf-8')
 
 153         etree.SubElement(head, 'title').text = document.meta.title
 
 159             content="width=device-width, initial-scale=1, maximum-scale=1"
 
 162         if self.no_externalities:
 
 165             ).text = urlopen(self.css_url).read().decode('utf-8')
 
 177                 src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"
 
 183                 src="http://malsup.github.io/min/jquery.cycle2.min.js"
 
 187 class SnippetHtmlBuilder(HtmlBuilder):
 
 191     with_footnotes = False
 
 192     with_nota_red = False
 
 196 class DaisyHtmlBuilder(StandaloneHtmlBuilder):
 
 197     file_extension = 'xhtml'
 
 201     with_footnotes = False
 
 202     with_nota_red = False
 
 203     with_deep_identifiers = False
 
 204     no_externalities = True
 
 207         tree = etree.ElementTree(self.tree)
 
 208         tree.docinfo.public_id = '-//W3C//DTD XHTML 1.0 Transitional//EN'
 
 209         tree.docinfo.system_url = 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'
 
 210         return OutputFile.from_bytes(