From c1000fe83b652dcd85b8fc57b60567e3d93aa5c9 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Mon, 25 Feb 2013 12:01:34 +0100 Subject: [PATCH 01/16] Scalable metrics in Cover --- librarian/cover.py | 150 ++++++++++++++++++++++++++++----------------- scripts/book2cover | 10 ++- 2 files changed, 101 insertions(+), 59 deletions(-) diff --git a/librarian/cover.py b/librarian/cover.py index be34e26..9fb01b7 100644 --- a/librarian/cover.py +++ b/librarian/cover.py @@ -9,6 +9,19 @@ from StringIO import StringIO from librarian import get_resource, OutputFile, URLOpener +class Metric(object): + """Gets metrics from an object, scaling it by a factor.""" + def __init__(self, obj, scale): + self._obj = obj + self._scale = float(scale) + + def __getattr__(self, name): + src = getattr(self._obj, name) + if src and self._scale: + src = type(src)(self._scale * src) + return src + + class TextBox(object): """Creates an Image with a series of centered strings.""" @@ -94,7 +107,8 @@ class Cover(object): author_lineskip = 40 author_color = '#000' author_shadow = None - author_font = None + author_font_ttf = get_resource('fonts/DejaVuSerif.ttf') + author_font_size = 30 title_top = 100 title_margin_left = 20 @@ -102,13 +116,15 @@ class Cover(object): title_lineskip = 54 title_color = '#000' title_shadow = None - title_font = None + title_font_ttf = get_resource('fonts/DejaVuSerif.ttf') + title_font_size = 40 logo_bottom = None logo_width = None uses_dc_cover = False format = 'JPEG' + scale = 1 exts = { 'JPEG': 'jpg', @@ -120,11 +136,14 @@ class Cover(object): 'PNG': 'image/png', } - def __init__(self, book_info, format=None): + def __init__(self, book_info, format=None, width=None, height=None): self.author = ", ".join(auth.readable() for auth in book_info.authors) self.title = book_info.title if format is not None: self.format = format + scale = max(float(width or 0) / self.width, float(height or 0) / self.height) + if scale: + self.scale = scale def pretty_author(self): """Allows for decorating author's name.""" @@ -135,7 +154,8 @@ class Cover(object): return self.title def image(self): - img = Image.new('RGB', (self.width, self.height), self.background_color) + metr = Metric(self, self.scale) + img = Image.new('RGB', (metr.width, metr.height), self.background_color) if self.background_img: background = Image.open(self.background_img) @@ -143,34 +163,35 @@ class Cover(object): del background # WL logo - if self.logo_width: + if metr.logo_width: logo = Image.open(get_resource('res/wl-logo.png')) - logo = logo.resize((self.logo_width, logo.size[1] * self.logo_width / logo.size[0])) - img.paste(logo, ((self.width - self.logo_width) / 2, img.size[1] - logo.size[1] - self.logo_bottom)) + logo = logo.resize((metr.logo_width, logo.size[1] * metr.logo_width / logo.size[0])) + img.paste(logo, ((metr.width - metr.logo_width) / 2, img.size[1] - logo.size[1] - metr.logo_bottom)) - top = self.author_top + top = metr.author_top tbox = TextBox( - self.width - self.author_margin_left - self.author_margin_right, - self.height - top, + metr.width - metr.author_margin_left - metr.author_margin_right, + metr.height - top, ) - author_font = self.author_font or ImageFont.truetype( - get_resource('fonts/DejaVuSerif.ttf'), 30) + + author_font = ImageFont.truetype( + self.author_font_ttf, metr.author_font_size) tbox.text(self.pretty_author(), self.author_color, author_font, - self.author_lineskip, self.author_shadow) + metr.author_lineskip, self.author_shadow) text_img = tbox.image() - img.paste(text_img, (self.author_margin_left, top), text_img) + img.paste(text_img, (metr.author_margin_left, top), text_img) - top += text_img.size[1] + self.title_top + top += text_img.size[1] + metr.title_top tbox = TextBox( - self.width - self.title_margin_left - self.title_margin_right, - self.height - top, + metr.width - metr.title_margin_left - metr.title_margin_right, + metr.height - top, ) - title_font = self.author_font or ImageFont.truetype( - get_resource('fonts/DejaVuSerif.ttf'), 40) + title_font = ImageFont.truetype( + self.title_font_ttf, metr.title_font_size) tbox.text(self.pretty_title(), self.title_color, title_font, - self.title_lineskip, self.title_shadow) + metr.title_lineskip, self.title_shadow) text_img = tbox.image() - img.paste(text_img, (self.title_margin_left, top), text_img) + img.paste(text_img, (metr.title_margin_left, top), text_img) return img @@ -181,7 +202,7 @@ class Cover(object): return self.exts[self.format] def save(self, *args, **kwargs): - return self.image().save(format=self.format, *args, **kwargs) + return self.image().save(format=self.format, quality=95, *args, **kwargs) def output_file(self, *args, **kwargs): imgstr = StringIO() @@ -194,13 +215,23 @@ class WLCover(Cover): width = 600 height = 833 uses_dc_cover = True - author_font = ImageFont.truetype( - get_resource('fonts/JunicodeWL-Regular.ttf'), 20) + author_font_ttf = get_resource('fonts/JunicodeWL-Regular.ttf') + author_font_size = 20 author_lineskip = 30 - title_font = ImageFont.truetype( - get_resource('fonts/DejaVuSerif-Bold.ttf'), 30) + title_font_ttf = get_resource('fonts/DejaVuSerif-Bold.ttf') + title_font_size = 30 title_lineskip = 40 title_box_width = 350 + + box_top_margin = 100 + box_bottom_margin = 100 + box_padding_y = 20 + box_above_line = 10 + box_below_line = 15 + box_line_left = 75 + box_line_right = 275 + box_line_width = 2 + bar_width = 35 background_color = '#444' author_color = '#444' @@ -220,19 +251,13 @@ class WLCover(Cover): u'Współczesność': '#06393d', } - def __init__(self, book_info, format=None, image_cache=None): - super(WLCover, self).__init__(book_info, format=format) + def __init__(self, book_info, format=None, width=None, height=None): + super(WLCover, self).__init__(book_info, format=format, width=width, height=height) self.kind = book_info.kind self.epoch = book_info.epoch if book_info.cover_url: url = book_info.cover_url bg_src = None - if image_cache: - from urllib import quote - try: - bg_src = URLOpener().open(image_cache + quote(url, safe="")) - except: - pass if bg_src is None: bg_src = URLOpener().open(url) self.background_img = StringIO(bg_src.read()) @@ -244,18 +269,19 @@ class WLCover(Cover): return self.author.upper() def image(self): - img = Image.new('RGB', (self.width, self.height), self.background_color) + metr = Metric(self, self.scale) + img = Image.new('RGB', (metr.width, metr.height), self.background_color) draw = ImageDraw.Draw(img) if self.epoch in self.epoch_colors: epoch_color = self.epoch_colors[self.epoch] else: epoch_color = '#000' - draw.rectangle((0, 0, self.bar_width, self.height), fill=epoch_color) + draw.rectangle((0, 0, metr.bar_width, metr.height), fill=epoch_color) if self.background_img: src = Image.open(self.background_img) - trg_size = (self.width - self.bar_width, self.height) + trg_size = (metr.width - metr.bar_width, metr.height) if src.size[0] * trg_size[1] < src.size[1] * trg_size[0]: resized = ( trg_size[0], @@ -273,25 +299,29 @@ class WLCover(Cover): src = src.resize(resized) src = src.crop((cut, 0, src.size[0] - cut, src.size[1])) - img.paste(src, (self.bar_width, 0)) + img.paste(src, (metr.bar_width, 0)) del src - box = TextBox(self.title_box_width, self.height, padding_y=20) + box = TextBox(metr.title_box_width, metr.height, padding_y=metr.box_padding_y) + author_font = ImageFont.truetype( + self.author_font_ttf, metr.author_font_size) box.text(self.pretty_author(), - font=self.author_font, - line_height=self.author_lineskip, + font=author_font, + line_height=metr.author_lineskip, color=self.author_color, shadow_color=self.author_shadow, ) - box.skip(10) - box.draw.line((75, box.height, 275, box.height), - fill=self.author_color, width=2) - box.skip(15) + box.skip(metr.box_above_line) + box.draw.line((metr.box_line_left, box.height, metr.box_line_right, box.height), + fill=self.author_color, width=metr.box_line_width) + box.skip(metr.box_below_line) + title_font = ImageFont.truetype( + self.title_font_ttf, metr.title_font_size) box.text(self.pretty_title(), - line_height=self.title_lineskip, - font=self.title_font, + line_height=metr.title_lineskip, + font=title_font, color=epoch_color, shadow_color=self.title_shadow, ) @@ -299,15 +329,15 @@ class WLCover(Cover): if self.kind == 'Liryka': # top - box_top = 100 + box_top = metr.box_top_margin elif self.kind == 'Epika': # bottom - box_top = self.height - 100 - box_img.size[1] + box_top = metr.height - metr.box_bottom_margin - box_img.size[1] else: # center - box_top = (self.height - box_img.size[1]) / 2 + box_top = (metr.height - box_img.size[1]) / 2 - box_left = self.bar_width + (self.width - self.bar_width - + box_left = metr.bar_width + (metr.width - metr.bar_width - box_img.size[0]) / 2 draw.rectangle((box_left, box_top, box_left + box_img.size[0], box_top + box_img.size[1]), @@ -338,7 +368,8 @@ class PrestigioCover(Cover): author_lineskip = 60 author_color = '#fff' author_shadow = '#000' - author_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Italic.ttf'), 50) + author_font_ttf = get_resource('fonts/JunicodeWL-Italic.ttf') + author_font_size = 50 title_top = 0 title_margin_left = 118 @@ -346,7 +377,8 @@ class PrestigioCover(Cover): title_lineskip = 60 title_color = '#fff' title_shadow = '#000' - title_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Italic.ttf'), 50) + title_font_ttf = get_resource('fonts/JunicodeWL-Italic.ttf') + title_font_size = 50 def pretty_title(self): return u"„%s”" % self.title @@ -362,14 +394,16 @@ class BookotekaCover(Cover): author_margin_right = 233 author_lineskip = 156 author_color = '#d9d919' - author_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Regular.ttf'), 130) + author_font_ttf = get_resource('fonts/JunicodeWL-Regular.ttf') + author_font_size = 130 title_top = 400 title_margin_left = 307 title_margin_right = 233 title_lineskip = 168 title_color = '#d9d919' - title_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Regular.ttf'), 140) + title_font_ttf = get_resource('fonts/JunicodeWL-Regular.ttf') + title_font_size = 140 format = 'PNG' @@ -378,8 +412,10 @@ class GandalfCover(Cover): width = 600 height = 730 background_img = get_resource('res/cover-gandalf.png') - author_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Regular.ttf'), 30) - title_font = ImageFont.truetype(get_resource('fonts/JunicodeWL-Regular.ttf'), 40) + author_font_ttf = get_resource('fonts/JunicodeWL-Regular.ttf') + author_font_size = 30 + title_font_ttf = get_resource('fonts/JunicodeWL-Regular.ttf') + title_font_size = 40 logo_bottom = 25 logo_width = 250 format = 'PNG' diff --git a/scripts/book2cover b/scripts/book2cover index 3cc0ed7..6cda7b3 100755 --- a/scripts/book2cover +++ b/scripts/book2cover @@ -14,10 +14,16 @@ class Book2Cover(Book2Anything): ext = "jpg" uses_cover = True cover_optional = False + transform_options = [ + Option('-W', '--width', action='store', type='int', dest='width', default=None, + help='Set width.'), + Option('-H', '--height', action='store', type='int', dest='height', default=None, + help='Set height.'), + ] @staticmethod - def transform(wldoc, cover): - return wldoc.as_cover(cover_class=cover) + def transform(wldoc, cover, *args, **kwargs): + return wldoc.as_cover(cover_class=cover, *args, **kwargs) if __name__ == '__main__': -- 2.20.1 From 0cefa871f6f1253be544a39c51e1f66f536805ce Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Mon, 25 Feb 2013 13:33:17 +0100 Subject: [PATCH 02/16] Add WL logo on cover --- librarian/cover.py | 29 +++++++++++++++++++++++------ scripts/book2cover | 4 ++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/librarian/cover.py b/librarian/cover.py index 9fb01b7..a37b911 100644 --- a/librarian/cover.py +++ b/librarian/cover.py @@ -4,7 +4,7 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # import re -import Image, ImageFont, ImageDraw, ImageFilter +import Image, ImageFont, ImageDraw, ImageFilter, ImageEnhance from StringIO import StringIO from librarian import get_resource, OutputFile, URLOpener @@ -231,7 +231,10 @@ class WLCover(Cover): box_line_left = 75 box_line_right = 275 box_line_width = 2 - + + logo_top = 15 + logo_width = 140 + bar_width = 35 background_color = '#444' author_color = '#444' @@ -251,10 +254,11 @@ class WLCover(Cover): u'Współczesność': '#06393d', } - def __init__(self, book_info, format=None, width=None, height=None): + def __init__(self, book_info, format=None, width=None, height=None, with_logo=False): super(WLCover, self).__init__(book_info, format=format, width=width, height=height) self.kind = book_info.kind self.epoch = book_info.epoch + self.with_logo = with_logo if book_info.cover_url: url = book_info.cover_url bg_src = None @@ -288,7 +292,7 @@ class WLCover(Cover): src.size[1] * trg_size[0] / src.size[0] ) cut = (resized[1] - trg_size[1]) / 2 - src = src.resize(resized) + src = src.resize(resized, Image.ANTIALIAS) src = src.crop((0, cut, src.size[0], src.size[1] - cut)) else: resized = ( @@ -296,7 +300,7 @@ class WLCover(Cover): trg_size[1], ) cut = (resized[0] - trg_size[0]) / 2 - src = src.resize(resized) + src = src.resize(resized, Image.ANTIALIAS) src = src.crop((cut, 0, src.size[0] - cut, src.size[1])) img.paste(src, (metr.bar_width, 0)) @@ -325,6 +329,15 @@ class WLCover(Cover): color=epoch_color, shadow_color=self.title_shadow, ) + + if self.with_logo: + logo = Image.open(get_resource('res/wl-logo-mono.png')) + logo = logo.resize((metr.logo_width, logo.size[1] * metr.logo_width / logo.size[0]), Image.ANTIALIAS) + alpha = logo.split()[3] + alpha = ImageEnhance.Brightness(alpha).enhance(.75) + logo.putalpha(alpha) + box.skip(metr.logo_top + logo.size[1]) + box_img = box.image() if self.kind == 'Liryka': @@ -344,8 +357,12 @@ class WLCover(Cover): fill='#fff') img.paste(box_img, (box_left, box_top), box_img) - return img + if self.with_logo: + img.paste(logo, + (box_left + (box_img.size[0] - logo.size[0]) / 2, + box_top + box_img.size[1] - metr.box_padding_y - logo.size[1]), mask=logo) + return img class VirtualoCover(Cover): diff --git a/scripts/book2cover b/scripts/book2cover index 6cda7b3..758ab0e 100755 --- a/scripts/book2cover +++ b/scripts/book2cover @@ -14,11 +14,15 @@ class Book2Cover(Book2Anything): ext = "jpg" uses_cover = True cover_optional = False + transform_options = [ Option('-W', '--width', action='store', type='int', dest='width', default=None, help='Set width.'), Option('-H', '--height', action='store', type='int', dest='height', default=None, help='Set height.'), + Option('-l', '--with-logo', dest='with_logo', + action='store_true', default=False, + help='Add WL logo in white box.'), ] @staticmethod -- 2.20.1 From 181c5739f47d2adb00ba115bb4766584a1bc37e4 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Fri, 26 Apr 2013 13:18:18 +0200 Subject: [PATCH 03/16] Add table of themes directly to HTML. --- librarian/html.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/librarian/html.py b/librarian/html.py index c1a5e5b..f29a9b9 100644 --- a/librarian/html.py +++ b/librarian/html.py @@ -57,6 +57,7 @@ def transform(wldoc, stylesheet='legacy', options=None, flags=None): if html_has_content(result): add_anchors(result.getroot()) + add_table_of_themes(result.getroot()) add_table_of_contents(result.getroot()) return OutputFile.from_string(etree.tostring(result, method='html', @@ -263,6 +264,33 @@ def add_table_of_contents(root): root.insert(0, toc) + +def add_table_of_themes(root): + try: + from sortify import sortify + except ImportError: + sortify = lambda x: x + + book_themes = {} + for fragment in root.findall('.//a[@class="theme-begin"]'): + if not fragment.text: + continue + theme_names = [s.strip() for s in fragment.text.split(',')] + for theme_name in theme_names: + book_themes.setdefault(theme_name, []).append(fragment.get('name')) + book_themes = book_themes.items() + book_themes.sort(key=lambda s: sortify(s[0])) + themes_div = etree.Element('div', id="themes") + themes_ol = etree.SubElement(themes_div, 'ol') + for theme_name, fragments in book_themes: + themes_li = etree.SubElement(themes_ol, 'li') + themes_li.text = "%s: " % theme_name + for i, fragment in enumerate(fragments): + item = etree.SubElement(themes_li, 'a', href="#%s" % fragment) + item.text = str(i + 1) + root.insert(0, themes_div) + + def extract_annotations(html_path): """For each annotation, yields a tuple: anchor, text, html.""" -- 2.20.1 From c17fc836d48e47367d8ed6966300923f7454e6bd Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Thu, 2 May 2013 12:18:12 +0200 Subject: [PATCH 04/16] forgotten image --- librarian/res/wl-logo-mono.png | Bin 0 -> 19534 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 librarian/res/wl-logo-mono.png diff --git a/librarian/res/wl-logo-mono.png b/librarian/res/wl-logo-mono.png new file mode 100644 index 0000000000000000000000000000000000000000..c99447e2bc8cf38f1abbe3d48e257fb12e802acb GIT binary patch literal 19534 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 iJgKU$wOx6qcK#nc?MHhaClXZv0000 Date: Fri, 28 Jun 2013 11:20:05 +0200 Subject: [PATCH 05/16] Spaces in themes list in HTML. --- librarian/html.py | 1 + 1 file changed, 1 insertion(+) diff --git a/librarian/html.py b/librarian/html.py index f29a9b9..70fc6e5 100644 --- a/librarian/html.py +++ b/librarian/html.py @@ -288,6 +288,7 @@ def add_table_of_themes(root): for i, fragment in enumerate(fragments): item = etree.SubElement(themes_li, 'a', href="#%s" % fragment) item.text = str(i + 1) + item.tail = ' ' root.insert(0, themes_div) -- 2.20.1 From 85ab1e2d4b363dc747eacda08fa254586905cf25 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 16 Jul 2013 11:41:45 +0200 Subject: [PATCH 06/16] Use Pillow-compatible imports. --- librarian/cover.py | 2 +- setup.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/librarian/cover.py b/librarian/cover.py index a37b911..8b770ca 100644 --- a/librarian/cover.py +++ b/librarian/cover.py @@ -4,7 +4,7 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # import re -import Image, ImageFont, ImageDraw, ImageFilter, ImageEnhance +from PIL import Image, ImageFont, ImageDraw, ImageFilter, ImageEnhance from StringIO import StringIO from librarian import get_resource, OutputFile, URLOpener diff --git a/setup.py b/setup.py index 51003ef..b20040a 100755 --- a/setup.py +++ b/setup.py @@ -32,7 +32,10 @@ setup( package_data={'librarian': ['xslt/*.xslt', 'epub/*', 'mobi/*', 'pdf/*', 'fb2/*', 'fonts/*', 'res/*'] + whole_tree(os.path.join(os.path.dirname(__file__), 'librarian'), 'font-optimizer')}, include_package_data=True, - install_requires=['lxml>=2.2'], + install_requires=[ + 'lxml>=2.2', + 'Pillow', + ], scripts=['scripts/book2html', 'scripts/book2txt', 'scripts/book2epub', -- 2.20.1 From 962000a4e998605544eade93edc2a046377db771 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 16 Jul 2013 12:08:00 +0200 Subject: [PATCH 07/16] Added theme table in test --- tests/files/text/asnyk_miedzy_nami_expected.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/files/text/asnyk_miedzy_nami_expected.html b/tests/files/text/asnyk_miedzy_nami_expected.html index e70e1bd..fd18174 100644 --- a/tests/files/text/asnyk_miedzy_nami_expected.html +++ b/tests/files/text/asnyk_miedzy_nami_expected.html @@ -3,6 +3,10 @@

Spis treści

    +

    Adam AsnykMiłość platonicznaMiędzy nami nic nie było

    -- 2.20.1 From b6b6be3f7ad18e33d80093d14096897aea1feb2c Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 16 Jul 2013 14:01:15 +0200 Subject: [PATCH 08/16] fixes #2620: remove old tagline --- librarian/res/wl-logo-small.png | Bin 9286 -> 7534 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/librarian/res/wl-logo-small.png b/librarian/res/wl-logo-small.png index 104d56ae9689e39163bc31a177651e5f9354b9ac..b32c46da1130e0260c0be634754e1c6225b8bbdf 100644 GIT binary patch literal 7534 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 -- 2.20.1 From c2d3ff4643de9a2bfbb462d5a82982896e4454bc Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 16 Jul 2013 14:25:08 +0200 Subject: [PATCH 09/16] Fixes #2631: losing whitespace in epub/mobi stanzas. --- librarian/epub.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/librarian/epub.py b/librarian/epub.py index 10922d4..6ab4928 100644 --- a/librarian/epub.py +++ b/librarian/epub.py @@ -117,10 +117,10 @@ class Stanza(object): Slashes may only occur directly in the stanza. Any slashes in subelements will be ignored, and the subelements will be put inside verse elements. - >>> s = etree.fromstring("a/\\nbx/\\nyc/ \\nd") + >>> s = etree.fromstring("a c c/\\nbx/\\nyc/ \\nd") >>> Stanza(s).versify() >>> print etree.tostring(s) - abx/ + a c cbx/ ycd """ @@ -149,16 +149,16 @@ class Stanza(object): return self.open_verse def push_text(self, text): - if not text or not text.strip(): + if not text: return for i, verse_text in enumerate(re.split(r"/\s*\n", text)): if i: self.open_normal_verse() verse = self.get_open_verse() if len(verse): - verse[-1].tail = (verse[-1].tail or "") + verse_text.strip() + verse[-1].tail = (verse[-1].tail or "") + verse_text else: - verse.text = (verse.text or "") + verse_text.strip() + verse.text = (verse.text or "") + verse_text def push_elem(self, elem): if elem.tag.startswith("wers"): -- 2.20.1 From 29ab945cc98e1bec1fed86eedd69c26479f52380 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Mon, 22 Jul 2013 15:09:21 +0200 Subject: [PATCH 10/16] #2773: support info in pdf/epub/mobi. --- librarian/epub.py | 9 +++++++ librarian/epub/support.html | 48 +++++++++++++++++++++++++++++++++++++ librarian/epub/xsltLast.xsl | 7 ------ librarian/pdf/wl.cls | 26 +++++++++++++++++++- librarian/pdf/wl2tex.xslt | 4 ++-- 5 files changed, 84 insertions(+), 10 deletions(-) create mode 100755 librarian/epub/support.html diff --git a/librarian/epub.py b/librarian/epub.py index 6ab4928..eab2b18 100644 --- a/librarian/epub.py +++ b/librarian/epub.py @@ -506,6 +506,15 @@ def transform(wldoc, verbose=False, zip.writestr('OPS/annotations.html', etree.tostring( html_tree, method="html", pretty_print=True)) + toc.add("Weprzyj Wolne Lektury", "support.html") + manifest.append(etree.fromstring( + '')) + spine.append(etree.fromstring( + '')) + html_string = open(get_resource('epub/support.html')).read() + chars.update(used_chars(etree.fromstring(html_string))) + zip.writestr('OPS/support.html', html_string) + toc.add("Strona redakcyjna", "last.html") manifest.append(etree.fromstring( '')) diff --git a/librarian/epub/support.html b/librarian/epub/support.html new file mode 100755 index 0000000..8ca550b --- /dev/null +++ b/librarian/epub/support.html @@ -0,0 +1,48 @@ + + + + + Wesprzyj Wolne Lektury + + + +
    + +

    Wesprzyj Wolne Lektury!

    + +

    + Wolne Lektury to projekt fundacji Nowoczesna Polska – organizacji + pożytku publicznego działającej na rzecz wolności korzystania + z dóbr kultury.

    + +

    + Co roku do domeny publicznej przechodzi twórczość kolejnych autorów. + Dzięki Twojemu wsparciu będziemy je mogli udostępnić wszystkim bezpłatnie. +

    + +

    + Jak możesz pomóc? +

    + +

    + Logo 1%
    + Przekaż 1% podatku na rozwój Wolnych Lektur:
    + Fundacja Nowoczesna Polska
    + KRS 0000070056 +

    + +

    + Pomóż uwolnić konkretną książkę, wspierając + zbiórkę + na stronie wolnelektury.pl. +

    + +

    + Przekaż darowiznę na konto: + szczegóły + na stronie Fundacji. +

    + +
    + + diff --git a/librarian/epub/xsltLast.xsl b/librarian/epub/xsltLast.xsl index 5288443..9b52203 100644 --- a/librarian/epub/xsltLast.xsl +++ b/librarian/epub/xsltLast.xsl @@ -81,13 +81,6 @@

    -
    - Logo 1% -
    Przekaż 1% podatku na rozwój Wolnych Lektur.
    -
    Nazwa organizacji: Fundacja Nowoczesna Polska
    -
    KRS 0000070056
    -
    -

     

    Plik wygenerowany dnia . diff --git a/librarian/pdf/wl.cls b/librarian/pdf/wl.cls index c387b03..4a7648e 100644 --- a/librarian/pdf/wl.cls +++ b/librarian/pdf/wl.cls @@ -246,8 +246,32 @@ Letters={SmallCaps,UppercaseSmallCaps} \editors + \ifdefined\coverby + \vspace{.6em} + \coverby + \fi + \vspace{.6em} - \coverby + \emph{Wesprzyj Wolne Lektury!} + + Wolne Lektury to projekt fundacji Nowoczesna Polska – organizacji + pożytku publicznego działającej na rzecz wolności korzystania + z dóbr kultury. + + Co roku do domeny publicznej przechodzi twórczość kolejnych autorów. + Dzięki Twojemu wsparciu będziemy je mogli udostępnić wszystkim bezpłatnie. + + \vspace{.6em} + \emph{Jak możesz pomóc?} + + Przekaż 1\% podatku na rozwój Wolnych Lektur: + Fundacja Nowoczesna Polska, KRS 0000070056. + + Pomóż uwolnić konkretną książkę, wspierając + \href{http://www.wolnelektury.pl/wesprzyj/}{zbiórkę na stronie wolnelektury.pl}. + + Przekaż darowiznę na konto: + \href{http://nowoczesnapolska.org.pl/pomoz-nam/wesprzyj-nas/}{szczegóły na stronie Fundacji}. \color{black} } diff --git a/librarian/pdf/wl2tex.xslt b/librarian/pdf/wl2tex.xslt index 909cf4b..e4b281b 100644 --- a/librarian/pdf/wl2tex.xslt +++ b/librarian/pdf/wl2tex.xslt @@ -88,8 +88,8 @@ - \def\coverby{ Okładka na podstawie: + \def\coverby{ \href{\datacoversource}{\datacoverby} @@ -98,8 +98,8 @@ \datacoverby{} - } + \def\editors{} -- 2.20.1 From b56beb67ff25d7a6ae42c841b9f10e681a748e22 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 24 Jul 2013 22:41:58 +0200 Subject: [PATCH 11/16] PDF cover info fix --- librarian/pdf/wl2tex.xslt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/librarian/pdf/wl2tex.xslt b/librarian/pdf/wl2tex.xslt index e4b281b..97296e9 100644 --- a/librarian/pdf/wl2tex.xslt +++ b/librarian/pdf/wl2tex.xslt @@ -88,8 +88,8 @@ - Okładka na podstawie: - \def\coverby{ + + \def\coverby{Okładka na podstawie: \href{\datacoversource}{\datacoverby} -- 2.20.1 From 5ecf203ebb02e8b60616d210f81908bcf3da2634 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 7 Aug 2013 12:19:28 +0200 Subject: [PATCH 12/16] Add funders info. --- librarian/dcparser.py | 2 ++ librarian/epub.py | 3 +++ librarian/epub/style.css | 4 +++- librarian/epub/xsltLast.xsl | 11 ++++++++++- librarian/pdf.py | 2 ++ librarian/pdf/wl.cls | 5 +++++ librarian/pdf/wl2tex.xslt | 6 +++++- 7 files changed, 30 insertions(+), 3 deletions(-) diff --git a/librarian/dcparser.py b/librarian/dcparser.py index eddd8e5..abee11b 100644 --- a/librarian/dcparser.py +++ b/librarian/dcparser.py @@ -171,6 +171,8 @@ class WorkInfo(object): as_person, salias='editor', multiple=True, default=[]), Field( DCNS('contributor.technical_editor'), 'technical_editors', as_person, salias='technical_editor', multiple=True, default=[]), + Field( DCNS('contributor.funding'), 'funders', + salias='funder', multiple=True, default=[]), Field( DCNS('date'), 'created_at', as_date), Field( DCNS('date.pd'), 'released_to_public_domain_at', as_date, required=False), diff --git a/librarian/epub.py b/librarian/epub.py index eab2b18..24579d9 100644 --- a/librarian/epub.py +++ b/librarian/epub.py @@ -415,6 +415,9 @@ def transform(wldoc, verbose=False, # add editors info document.edoc.getroot().set('editors', u', '.join(sorted( editor.readable() for editor in document.editors()))) + if document.book_info.funders: + document.edoc.getroot().set('funders', u', '.join( + document.book_info.funders)) opf = xslt(document.book_info.to_etree(), get_resource('epub/xsltContent.xsl')) manifest = opf.find('.//' + OPFNS('manifest')) diff --git a/librarian/epub/style.css b/librarian/epub/style.css index 622c8da..a862dce 100644 --- a/librarian/epub/style.css +++ b/librarian/epub/style.css @@ -364,7 +364,9 @@ em.author-emphasis margin-right: 2em; } -p.minor { +p.minor-info { + text-align: center; + margin-bottom: 1em; font-size: 0.75em; } p.footer { diff --git a/librarian/epub/xsltLast.xsl b/librarian/epub/xsltLast.xsl index 9b52203..c4867d1 100644 --- a/librarian/epub/xsltLast.xsl +++ b/librarian/epub/xsltLast.xsl @@ -63,6 +63,8 @@ + +

    Okładka na podstawie: @@ -82,7 +84,7 @@

     

    -

    +

    Plik wygenerowany dnia .

    @@ -103,6 +105,13 @@ + + +

    Publikację ufundowali i ufundowały: + .

    +
    +
    + diff --git a/librarian/pdf.py b/librarian/pdf.py index 9fb92b1..90e4dc2 100644 --- a/librarian/pdf.py +++ b/librarian/pdf.py @@ -231,6 +231,8 @@ def transform(wldoc, verbose=False, save_tex=None, morefloats=None, # add editors info root.set('editors', u', '.join(sorted( editor.readable() for editor in document.editors()))) + if document.book_info.funders: + root.set('funders', u', '.join(document.book_info.funders)) # hack the tree move_motifs_inside(document.edoc) diff --git a/librarian/pdf/wl.cls b/librarian/pdf/wl.cls index 4a7648e..0de767c 100644 --- a/librarian/pdf/wl.cls +++ b/librarian/pdf/wl.cls @@ -246,6 +246,11 @@ Letters={SmallCaps,UppercaseSmallCaps} \editors + \ifdefined\funders + \vspace{.6em} + \funders + \fi + \ifdefined\coverby \vspace{.6em} \coverby diff --git a/librarian/pdf/wl2tex.xslt b/librarian/pdf/wl2tex.xslt index 97296e9..c0c22e5 100644 --- a/librarian/pdf/wl2tex.xslt +++ b/librarian/pdf/wl2tex.xslt @@ -100,7 +100,11 @@ } - \def\editors{} + \def\editors{} + + \def\funders{Publikację ufundowali i ufundowały: + .} + -- 2.20.1 From 547cb2febc3c9350fed0267dbcecd52768c83916 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 7 Aug 2013 12:37:22 +0200 Subject: [PATCH 13/16] funders in txt --- librarian/text.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/librarian/text.py b/librarian/text.py index d99e7cf..d92de3b 100644 --- a/librarian/text.py +++ b/librarian/text.py @@ -26,7 +26,7 @@ Utwór opracowany został w ramach projektu Wolne Lektury przez fundację Nowocz %(license_description)s.%(source)s -%(description)s%(contributors)s +%(description)s%(contributors)s%(funders)s """ def transform(wldoc, flags=None, **options): @@ -70,7 +70,10 @@ def transform(wldoc, flags=None, **options): contributors = ', '.join(person.readable() for person in sorted(set(p for p in (parsed_dc.technical_editors + parsed_dc.editors) if p))) if contributors: - contributors = "\n\nOpracowanie redakcyjne i przypisy: %s" % contributors + contributors = "\n\nOpracowanie redakcyjne i przypisy: %s." % contributors + funders = ', '.join(parsed_dc.funders) + if funders: + funders = u"\n\nPublikację ufundowali i ufundowały: %s." % funders else: description = 'Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl).' url = '*' * 10 @@ -78,6 +81,7 @@ def transform(wldoc, flags=None, **options): license_description = "" source = "" contributors = "" + funders = "" return OutputFile.from_string((TEMPLATE % { 'description': description, 'url': url, @@ -85,6 +89,7 @@ def transform(wldoc, flags=None, **options): 'text': unicode(result), 'source': source, 'contributors': contributors, + 'funders': funders, }).encode('utf-8')) else: return OutputFile.from_string(unicode(result).encode('utf-8')) -- 2.20.1 From 807df526faddb8682eb20cd0a61b39d18a84ff85 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 17 Sep 2013 16:14:35 +0200 Subject: [PATCH 14/16] Legal note fix. --- librarian/epub/xsltLast.xsl | 2 +- librarian/pdf/wl2tex.xslt | 2 +- librarian/text.py | 2 +- tests/files/text/asnyk_miedzy_nami_expected.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/librarian/epub/xsltLast.xsl b/librarian/epub/xsltLast.xsl index c4867d1..41afd36 100644 --- a/librarian/epub/xsltLast.xsl +++ b/librarian/epub/xsltLast.xsl @@ -32,7 +32,7 @@ - Ten utwór nie jest chroniony prawem autorskim i znajduje się w domenie + 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 diff --git a/librarian/pdf/wl2tex.xslt b/librarian/pdf/wl2tex.xslt index c0c22e5..353ecf9 100644 --- a/librarian/pdf/wl2tex.xslt +++ b/librarian/pdf/wl2tex.xslt @@ -151,7 +151,7 @@ \def\bookurl{} - \def\rightsinfo{Ten utwór nie jest chroniony prawem autorskim i~znajduje się w~domenie + \def\rightsinfo{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 diff --git a/librarian/text.py b/librarian/text.py index d92de3b..9a4fd7a 100644 --- a/librarian/text.py +++ b/librarian/text.py @@ -59,7 +59,7 @@ def transform(wldoc, flags=None, **options): if license: license_description = u"Ten utwór jest udostepniony na licencji %s: \n%s" % (license_description, license) else: - license_description = u"Ten utwór nie jest chroniony 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 Creative Commons Uznanie Autorstwa – Na Tych Samych Warunkach 3.0 PL (http://creativecommons.org/licenses/by-sa/3.0/)" + license_description = u"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 Creative Commons Uznanie Autorstwa – Na Tych Samych Warunkach 3.0 PL (http://creativecommons.org/licenses/by-sa/3.0/)" source = parsed_dc.source_name if source: diff --git a/tests/files/text/asnyk_miedzy_nami_expected.txt b/tests/files/text/asnyk_miedzy_nami_expected.txt index d300b3e..89e310a 100644 --- a/tests/files/text/asnyk_miedzy_nami_expected.txt +++ b/tests/files/text/asnyk_miedzy_nami_expected.txt @@ -33,7 +33,7 @@ Wersja lektury w opracowaniu merytorycznym i krytycznym (przypisy i motywy) dost Utwór opracowany został w ramach projektu Wolne Lektury przez fundację Nowoczesna Polska. -Ten utwór nie jest chroniony 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 Creative Commons Uznanie Autorstwa – Na Tych Samych Warunkach 3.0 PL (http://creativecommons.org/licenses/by-sa/3.0/). +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 Creative Commons Uznanie Autorstwa – Na Tych Samych Warunkach 3.0 PL (http://creativecommons.org/licenses/by-sa/3.0/). Tekst opracowany na podstawie: (Asnyk, Adam) El...y (1838-1897), Poezye, t. 3, Gebethner i Wolff, wyd. nowe poprzedzone słowem wstępnym St. Krzemińskiego, Warszawa, 1898 -- 2.20.1 From 9b0249cce34a32d19b364fd5e3d340f22cd9cde7 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Mon, 7 Oct 2013 09:53:56 +0200 Subject: [PATCH 15/16] typo --- librarian/epub.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarian/epub.py b/librarian/epub.py index 24579d9..f211ee4 100644 --- a/librarian/epub.py +++ b/librarian/epub.py @@ -509,7 +509,7 @@ def transform(wldoc, verbose=False, zip.writestr('OPS/annotations.html', etree.tostring( html_tree, method="html", pretty_print=True)) - toc.add("Weprzyj Wolne Lektury", "support.html") + toc.add("Wesprzyj Wolne Lektury", "support.html") manifest.append(etree.fromstring( '')) spine.append(etree.fromstring( -- 2.20.1 From ac6f4dfb3c4e7ac8b22ab56390e61634a8152df6 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 8 Oct 2013 12:04:25 +0200 Subject: [PATCH 16/16] Add thank-you note in EPUB and PDF. --- librarian/dcparser.py | 1 + librarian/epub.py | 2 ++ librarian/epub/xsltTitle.xsl | 4 ++++ librarian/pdf.py | 2 ++ librarian/pdf/wl.cls | 5 +++++ librarian/pdf/wl2tex.xslt | 5 +++++ 6 files changed, 19 insertions(+) diff --git a/librarian/dcparser.py b/librarian/dcparser.py index abee11b..a907a52 100644 --- a/librarian/dcparser.py +++ b/librarian/dcparser.py @@ -173,6 +173,7 @@ class WorkInfo(object): as_person, salias='technical_editor', multiple=True, default=[]), Field( DCNS('contributor.funding'), 'funders', salias='funder', multiple=True, default=[]), + Field( DCNS('contributor.thanks'), 'thanks', required=False), Field( DCNS('date'), 'created_at', as_date), Field( DCNS('date.pd'), 'released_to_public_domain_at', as_date, required=False), diff --git a/librarian/epub.py b/librarian/epub.py index f211ee4..bfd7570 100644 --- a/librarian/epub.py +++ b/librarian/epub.py @@ -418,6 +418,8 @@ def transform(wldoc, verbose=False, if document.book_info.funders: document.edoc.getroot().set('funders', u', '.join( document.book_info.funders)) + if document.book_info.thanks: + document.edoc.getroot().set('thanks', document.book_info.thanks) opf = xslt(document.book_info.to_etree(), get_resource('epub/xsltContent.xsl')) manifest = opf.find('.//' + OPFNS('manifest')) diff --git a/librarian/epub/xsltTitle.xsl b/librarian/epub/xsltTitle.xsl index 17739a8..9544e27 100644 --- a/librarian/epub/xsltTitle.xsl +++ b/librarian/epub/xsltTitle.xsl @@ -52,6 +52,10 @@

    + +

    .

    +
    +

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

    diff --git a/librarian/pdf.py b/librarian/pdf.py index 90e4dc2..b4edfdb 100644 --- a/librarian/pdf.py +++ b/librarian/pdf.py @@ -233,6 +233,8 @@ def transform(wldoc, verbose=False, save_tex=None, morefloats=None, editor.readable() for editor in document.editors()))) if document.book_info.funders: root.set('funders', u', '.join(document.book_info.funders)) + if document.book_info.thanks: + root.set('thanks', document.book_info.thanks) # hack the tree move_motifs_inside(document.edoc) diff --git a/librarian/pdf/wl.cls b/librarian/pdf/wl.cls index 0de767c..a9ace8e 100644 --- a/librarian/pdf/wl.cls +++ b/librarian/pdf/wl.cls @@ -215,6 +215,11 @@ Letters={SmallCaps,UppercaseSmallCaps} \vspace{.5em} \fi + \ifdefined\thanknote + \thanknote + \vspace{.5em} + \fi + Utwór opracowany został w ramach projektu \href{http://www.wolnelektury.pl/}{Wolne Lektury} przez \href{http://nowoczesnapolska.org.pl}{fundację Nowoczesna Polska}. diff --git a/librarian/pdf/wl2tex.xslt b/librarian/pdf/wl2tex.xslt index 353ecf9..ca948da 100644 --- a/librarian/pdf/wl2tex.xslt +++ b/librarian/pdf/wl2tex.xslt @@ -64,6 +64,11 @@ 210mm
    + + + \def\thanknote{} + + -- 2.20.1