X-Git-Url: https://git.mdrn.pl/librarian.git/blobdiff_plain/db91f942ce46e3af1420f3469a83257ef5aca4c2..d3d58ca2b55f820b1d5ce30260793e0848bb1247:/src/librarian/builders/epub.py?ds=sidebyside diff --git a/src/librarian/builders/epub.py b/src/librarian/builders/epub.py index 91405c3..e009d4a 100644 --- a/src/librarian/builders/epub.py +++ b/src/librarian/builders/epub.py @@ -1,17 +1,17 @@ +# This file is part of Librarian, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Wolne Lektury. See NOTICE for more information. +# from datetime import date +import io import os +import re import tempfile from ebooklib import epub from lxml import etree -import six from librarian import functions, OutputFile, get_resource, XHTMLNS from librarian.cover import make_cover from librarian.embeds.mathml import MathML -import librarian.epub from librarian.fonts import strip_font -from librarian.fundraising import FUNDRAISING - - class Xhtml: @@ -30,9 +30,11 @@ class Xhtml: class Builder: file_extension = None - def __init__(self, base_url=None): + def __init__(self, base_url=None, fundraising=None, cover=None): self._base_url = base_url or 'file:///home/rczajka/for/fnp/librarian/temp~/maly/img/' + self.fundraising = fundraising self.footnotes = etree.Element('div', id='footnotes') + self.make_cover = cover or make_cover self.cursors = { # None: None, @@ -60,8 +62,6 @@ class Builder: def forget_fragment(self, name): del self.cursors[name] - - @property def base_url(self): if self._base_url is not None: @@ -78,10 +78,14 @@ class Builder: class EpubBuilder(Builder): file_extension = 'epub' + isbn_field = 'isbn_epub' + orphans = True - def __init__(self, *args, **kwargs): + def __init__(self, *args, debug=False, **kwargs): self.chars = set() self.fundr = 0 + self.debug = debug + self.splits = [] super().__init__(*args, **kwargs) def build(self, document, **kwargs): @@ -109,7 +113,6 @@ class EpubBuilder(Builder): self.set_metadata() - self.add_cover() self.add_title_page() @@ -140,21 +143,21 @@ class EpubBuilder(Builder): self.add_support_page() self.add_last_page() + if self.fundraising: + e = len(self.output.spine) - 3 - 3 + nfunds = len(self.fundraising) + if e > 4 * nfunds: + nfunds *= 2 - e = len(self.output.spine) - 3 - 3 - nfunds = len(FUNDRAISING) - if e > 16: - nfunds *= 2 + # COUNTING CHARACTERS? + for f in range(nfunds): + spine_index = int(4 + (f / nfunds * e) + f) - # COUNTING CHARACTERS? - for f in range(nfunds): - spine_index = int(4 + (f / nfunds * e) + f) - - h = Xhtml() - h.body.append( - etree.XML('
' + FUNDRAISING[f % len(FUNDRAISING)] + '
') - ) - self.add_html(h.element, file_name='fund%d.xhtml' % f, spine=spine_index) + h = Xhtml() + h.body.append( + etree.XML('
' + self.fundraising[f % len(self.fundraising)] + '
') + ) + self.add_html(h.element, file_name='fund%d.xhtml' % f, spine=spine_index) self.add_fonts() @@ -202,7 +205,7 @@ class EpubBuilder(Builder): def add_title_page(self): html = Xhtml() html.title.text = "Strona tytułowa" - bt = etree.SubElement(html.body, 'div', **{'class': 'book-text'}) + bt = etree.SubElement(html.body, 'div', **{'id': 'book-text'}) tp = etree.SubElement(bt, 'div', **{'class': 'title-page'}) # Tak jak jest teraz – czy może być jednocześnie @@ -212,10 +215,10 @@ class EpubBuilder(Builder): e = self.document.tree.find('//autor_utworu') if e is not None: - etree.SubElement(tp, 'h2', **{'class': 'author'}).text = e.raw_printable_text() + etree.SubElement(tp, 'h2', **{'class': 'author'}).text = e.raw_printable_text(self) e = self.document.tree.find('//nazwa_utworu') if e is not None: - etree.SubElement(tp, 'h1', **{'class': 'title'}).text = e.raw_printable_text() + etree.SubElement(tp, 'h1', **{'class': 'title'}).text = e.raw_printable_text(self) if not len(tp): for author in self.document.meta.authors: @@ -237,7 +240,7 @@ class EpubBuilder(Builder): p = etree.XML("""

Ta lektura, podobnie jak tysiące innych, jest dostępna on-line na stronie - wolnelektury.pl. + wolnelektury.pl.

""") p[0].attrib['href'] = str(self.document.meta.url) tp.append(p) @@ -247,15 +250,15 @@ class EpubBuilder(Builder): tp.append(etree.XML("""

- Utwór opracowany został w ramach projektu Wolne Lektury przez fundację Nowoczesna Polska. + Utwór opracowany został w ramach projektu Wolne Lektury przez fundację Wolne Lektury.

""")) - if self.document.meta.isbn_epub: - etree.SubElement(tp, 'p', **{"class": "info"}).text = self.document.meta.isbn_epub + if getattr(self.document.meta, self.isbn_field): + etree.SubElement(tp, 'p', **{"class": "info"}).text = getattr(self.document.meta, self.isbn_field) tp.append(etree.XML("""""")) self.add_html( @@ -282,13 +285,13 @@ class EpubBuilder(Builder): for i, author in enumerate(self.document.meta.authors): self.output.add_author( author.readable(), - file_as=six.text_type(author), + file_as=str(author), uid='creator{}'.format(i) ) for translator in self.document.meta.translators: self.output.add_author( translator.readable(), - file_as=six.text_type(translator), + file_as=str(translator), role='trl', uid='translator{}'.format(i) ) @@ -302,6 +305,7 @@ class EpubBuilder(Builder): def add_toc(self): item = epub.EpubNav() + item.add_link(href='style.css', rel='stylesheet', type='text/css') self.output.add_item(item) self.output.spine.append(item) self.output.add_item(epub.EpubNcx()) @@ -318,7 +322,7 @@ class EpubBuilder(Builder): def add_support_page(self): self.add_file( - get_resource('epub/support.xhtml'), + get_resource('res/epub/support.xhtml'), spine=True, toc='Wesprzyj Wolne Lektury' ) @@ -328,7 +332,7 @@ class EpubBuilder(Builder): media_type='image/png' ) self.add_file( - get_resource('epub/style.css'), + get_resource('res/epub/style.css'), media_type='text/css' ) @@ -380,8 +384,6 @@ class EpubBuilder(Builder): doctype='' ) - html = librarian.epub.squeeze_whitespace(html) - self.add_file( content=html, **kwargs @@ -389,8 +391,6 @@ class EpubBuilder(Builder): def add_fonts(self): - print("".join(sorted(self.chars))) - # TODO: optimizer for fname in ('DejaVuSerif.ttf', 'DejaVuSerif-Bold.ttf', 'DejaVuSerif-Italic.ttf', 'DejaVuSerif-BoldItalic.ttf'): self.add_file( @@ -531,27 +531,46 @@ class EpubBuilder(Builder): newp = lambda: etree.SubElement(d, 'p', {'class': 'info'}) p = newp() + p.text = ( + "Wszystkie zasoby Wolnych Lektur możesz swobodnie wykorzystywać, " + "publikować i rozpowszechniać pod warunkiem zachowania warunków " + "licencji i zgodnie z " + ) + a = etree.SubElement(p, "a", href="https://wolnelektury.pl/info/zasady-wykorzystania/") + a.text = "Zasadami wykorzystania Wolnych Lektur" + a.tail = "." + + etree.SubElement(p, "br") + + if m.license: - p.text = """ - Ten utwór jest udostępniony na licencji - """ + p[-1].tail = "Ten utwór jest udostępniony na licencji " etree.SubElement(p, 'a', href=m.license).text = m.license_description else: - p.text = """ - Ten utwór nie jest objęty majątkowym prawem autorskim i znajduje się w domenie - publicznej, co oznacza że możesz go swobodnie wykorzystywać, publikować - i rozpowszechniać. Jeśli utwór opatrzony jest dodatkowymi materiałami - (przypisy, motywy literackie etc.), które podlegają prawu autorskiemu, to - te dodatkowe materiały udostępnione są na licencji - """ - a = etree.SubElement(p, "a", href="http://creativecommons.org/licenses/by-sa/3.0/") - a.text = """Creative Commons - Uznanie Autorstwa – Na Tych Samych Warunkach 3.0 PL""" - a.tail = "." + p[-1].tail = 'Ten utwór jest w domenie publicznej.' + etree.SubElement(p, "br") + + p[-1].tail = ( + "Wszystkie materiały dodatkowe (przypisy, motywy literackie) są " + "udostępnione na " + ) + etree.SubElement(p, 'a', href='https://artlibre.org/licence/lal/pl/').text = 'Licencji Wolnej Sztuki 1.3' + p[-1].tail = '.' + etree.SubElement(p, "br") + p[-1].tail = ( + "Fundacja Wolne Lektury zastrzega sobie prawa do wydania " + "krytycznego zgodnie z art. Art.99(2) Ustawy o prawach autorskich " + "i prawach pokrewnych. Wykorzystując zasoby z Wolnych Lektur, " + "należy pamiętać o zapisach licencji oraz zasadach, które " + "spisaliśmy w " + ) + + etree.SubElement(p, 'a', href='https://wolnelektury.pl/info/zasady-wykorzystania/').text = 'Zasadach wykorzystania Wolnych Lektur' + p[-1].tail = '. Zapoznaj się z nimi, zanim udostępnisz dalej nasze książki.' p = newp() - p.text = 'Źródło: ' + p.text = 'E-book można pobrać ze strony: ' etree.SubElement( p, 'a', href=str(m.url), title=', '.join(( @@ -560,7 +579,8 @@ class EpubBuilder(Builder): )) ).text = str(m.url) - newp().text = 'Tekst opracowany na podstawie: ' + m.source_name + if m.source_name: + newp().text = 'Tekst opracowany na podstawie: ' + m.source_name newp().text = """ Wydawca: @@ -570,9 +590,11 @@ class EpubBuilder(Builder): newp().text = m.description - if m.editors: + editors = self.document.editors() + if editors: newp().text = 'Opracowanie redakcyjne i przypisy: %s.' % ( - ', '.join(e.readable() for e in sorted(self.document.editors()))) + ', '.join(e.readable() for e in sorted(editors)) + ) if m.funders: etree.SubElement(d, 'p', {'class': 'minor-info'}).text = '''Publikację wsparli i wsparły: @@ -590,8 +612,8 @@ class EpubBuilder(Builder): else: p.text += m.cover_by - if m.isbn_epub: - newp().text = m.isbn_epub + if getattr(m, self.isbn_field): + newp().text = getattr(m, self.isbn_field) newp().text = '\u00a0' @@ -645,10 +667,10 @@ class EpubBuilder(Builder): def add_cover(self): # TODO: allow other covers - cover_maker = make_cover + cover_maker = self.make_cover - cover_file = six.BytesIO() - cover = cover_maker(self.document.meta) + cover_file = io.BytesIO() + cover = cover_maker(self.document.meta, width=600) cover.save(cover_file) cover_name = 'cover.%s' % cover.ext() @@ -673,7 +695,7 @@ class EpubBuilder(Builder): ''' % cover.ext()).encode('utf-8') self.add_file(file_name='cover.xhtml', content=ci) - self.output.spine.append('cover') + self.output.spine.append(('cover', 'no')) self.output.guide.append({ 'type': 'cover', 'href': 'cover.xhtml', @@ -688,3 +710,8 @@ class EpubBuilder(Builder): file_name=name ) return name + + def process_comment(self, comment): + m = re.match(r'TRIM:(\d+)', comment.text) + if m is not None: + self.splits.append(comment.sourceline - int(m.group(1)))