Merge branch 'pretty' into commerce
authorRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Thu, 19 Jan 2012 15:35:59 +0000 (16:35 +0100)
committerRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Thu, 19 Jan 2012 15:35:59 +0000 (16:35 +0100)
Conflicts:
librarian/cover.py
librarian/epub.py
librarian/epub/xsltContent.xsl
librarian/epub/xsltScheme.xsl
scripts/book2epub

12 files changed:
librarian/cover.py
librarian/epub.py
librarian/epub/style.css
librarian/epub/xsltContent.xsl
librarian/epub/xsltScheme.xsl
librarian/epub/xsltTitle.xsl
librarian/fonts/DroidSans.ttf [new file with mode: 0644]
librarian/fonts/EBGaramond-Regular.ttf [new file with mode: 0644]
librarian/packagers.py
librarian/res/cover-arta-tech.jpg [new file with mode: 0644]
scripts/book2epub
scripts/book2partner

index 63e4aa0..e7a8e1b 100644 (file)
@@ -34,22 +34,29 @@ class TextBox(object):
         self.height += height
 
     def text(self, text, color='#000', font=None, line_height=20, 
-             shadow_color=None):
+             shadow_color=None, shortener=None):
         """Writes some centered text."""
         if shadow_color:
             if not self.shadow_img:
                 self.shadow_img = Image.new('RGBA', self.img.size)
                 self.shadow_draw = ImageDraw.Draw(self.shadow_img)
         while text:
-            line = text
-            line_width = self.draw.textsize(line, font=font)[0]
-            while line_width > self.max_text_width:
-                parts = line.rsplit(' ', 1)
-                if len(parts) == 1:
-                    line_width = self.max_text_width
-                    break
-                line = parts[0]
+            if shortener:
+                for line in shortener(text):
+                    if text_draw.textsize(line, font=font)[0] <= self.max_text_width:
+                        break
+                text = ''
+            else:
+                line = text
                 line_width = self.draw.textsize(line, font=font)[0]
+                while line_width > self.max_text_width:
+                    parts = line.rsplit(' ', 1)
+                    if len(parts) == 1:
+                        line_width = self.max_text_width
+                        break
+                    line = parts[0]
+                    line_width = self.draw.textsize(line, font=font)[0]
+
             line = line.strip() + ' '
 
             pos_x = (self.max_width - line_width) / 2
@@ -65,6 +72,30 @@ class TextBox(object):
             # go to next line
             text = text[len(line):]
 
+    @staticmethod
+    def person_shortener(text):
+        yield text
+        chunks = text.split()
+        n_chunks = len(chunks)
+        # make initials from given names, starting from last
+        for i in range(n_chunks - 2, -1, -1):
+            chunks[i] = chunks[i][0] + '.'
+            yield " ".join(chunks)
+        # remove given names initials, starting from last
+        while len(chunks) > 2:
+            del chunks[1]
+            yield " ".join(chunks)
+
+    @staticmethod
+    def title_shortener(text):
+        yield text
+        chunks = text.split()
+        n_chunks = len(chunks)
+        # remove words, starting from last one
+        while len(chunks) > 1:
+            del chunks[-1]
+            yield " ".join(chunks) + u'…'
+
     def image(self):
         """Creates the actual Image object."""
         image = Image.new('RGBA', (self.max_width,
@@ -85,6 +116,7 @@ class Cover(object):
     background_color = '#fff'
     background_img = None
 
+    author_align = 'c'
     author_top = 100
     author_margin_left = 20
     author_margin_right = 20
@@ -92,7 +124,9 @@ class Cover(object):
     author_color = '#000'
     author_shadow = None
     author_font = None
+    author_wrap = True
 
+    title_align = 'c'
     title_top = 100
     title_margin_left = 20
     title_margin_right = 20
@@ -100,6 +134,7 @@ class Cover(object):
     title_color = '#000'
     title_shadow = None
     title_font = None
+    title_wrap = True
 
     logo_bottom = None
     logo_width = None
@@ -134,7 +169,10 @@ class Cover(object):
 
         if self.background_img:
             background = Image.open(self.background_img)
-            img.paste(background, None, background)
+            try:
+                img.paste(background, None, background)
+            except ValueError, e:
+                img.paste(background)
             del background
 
         # WL logo
@@ -150,8 +188,9 @@ class Cover(object):
             )
         author_font = self.author_font or ImageFont.truetype(
             get_resource('fonts/DejaVuSerif.ttf'), 30)
+        author_shortener = None if self.author_wrap else TextBox.person_shortener 
         tbox.text(self.pretty_author(), self.author_color, author_font,
-            self.author_lineskip, self.author_shadow)
+            self.author_lineskip, self.author_shadow, author_shortener)
         text_img = tbox.image()
         img.paste(text_img, (self.author_margin_left, top), text_img)
         
@@ -162,8 +201,9 @@ class Cover(object):
             )
         title_font = self.author_font or ImageFont.truetype(
             get_resource('fonts/DejaVuSerif.ttf'), 40)
+        title_shortener = None if self.title_wrap else TextBox.title_shortener 
         tbox.text(self.pretty_title(), self.title_color, title_font,
-            self.title_lineskip, self.title_shadow)
+            self.title_lineskip, self.title_shadow, title_shortener)
         text_img = tbox.image()
         img.paste(text_img, (self.title_margin_left, top), text_img)
 
@@ -364,3 +404,42 @@ class GandalfCover(Cover):
     logo_bottom = 25
     logo_width = 250
     format = 'PNG'
+
+
+class ArtaTechCover(Cover):
+    width = 600
+    height = 800
+    background_img = get_resource('res/cover-arta-tech.jpg')
+    author_top = 132
+    author_margin_left = 235
+    author_margin_right = 23
+    author_align = 'r'
+    author_font = ImageFont.truetype(get_resource('fonts/DroidSans.ttf'), 32)
+    author_color = '#555555'
+    author_wrap = False
+    title_top = 17
+    title_margin_right = 21
+    title_margin_left = 60
+    title_align = 'r'
+    title_font = ImageFont.truetype(get_resource('fonts/EBGaramond-Regular.ttf'), 42)
+    title_color = '#222222'
+    title_wrap = False
+    format = 'JPEG'
+
+    def pretty_author(self):
+        return self.author.upper()
+
+
+def ImageCover(img):
+    """ a class factory for simple image covers """
+    img = Image.open(img)
+
+    class ImgCover(Cover):
+        def image(self):
+            return img
+
+        @property
+        def format(self):
+            return self.image().format
+
+    return ImgCover
index 80941eb..48bb2f2 100644 (file)
@@ -5,6 +5,7 @@
 #
 from __future__ import with_statement
 
+from copy import deepcopy
 import os
 import os.path
 import subprocess
@@ -292,7 +293,7 @@ def transform(wldoc, verbose=False,
 
     sample=n: generate sample e-book (with at least n paragraphs)
     cover: a cover.Cover object or True for default
-    flags: less-advertising, without-fonts
+    flags: less-advertising, without-fonts, images, not-wl
     """
 
     def transform_file(wldoc, chunk_counter=1, first=True, sample=None):
@@ -374,6 +375,7 @@ def transform(wldoc, verbose=False,
     spine = opf.find('.//' + OPFNS('spine'))
 
     output_file = NamedTemporaryFile(prefix='librarian', suffix='.epub', delete=False)
+
     zip = zipfile.ZipFile(output_file, 'w', zipfile.ZIP_DEFLATED)
 
     # write static elements
@@ -387,8 +389,14 @@ def transform(wldoc, verbose=False,
                        '<rootfiles><rootfile full-path="OPS/content.opf" ' \
                        'media-type="application/oebps-package+xml" />' \
                        '</rootfiles></container>')
-    zip.write(get_resource('res/wl-logo-small.png'), os.path.join('OPS', 'logo_wolnelektury.png'))
-    zip.write(get_resource('res/jedenprocent.png'), os.path.join('OPS', 'jedenprocent.png'))
+    if not flags or 'not-wl' not in flags:
+        manifest.append(etree.fromstring(
+            '<item id="logo_wolnelektury" href="logo_wolnelektury.png" media-type="image/png" />'))
+        manifest.append(etree.fromstring(
+            '<item id="jedenprocent" href="jedenprocent.png" media-type="image/png" />'))
+        zip.write(get_resource('res/wl-logo-small.png'), os.path.join('OPS', 'logo_wolnelektury.png'))
+        zip.write(get_resource('res/jedenprocent.png'), os.path.join('OPS', 'jedenprocent.png'))
+
     if not style:
         style = get_resource('epub/style.css')
     zip.write(style, os.path.join('OPS', 'style.css'))
@@ -422,6 +430,26 @@ def transform(wldoc, verbose=False,
         opf.getroot()[0].append(etree.fromstring('<meta name="cover" content="cover-image"/>'))
         guide.append(etree.fromstring('<reference href="cover.html" type="cover" title="Okładka"/>'))
 
+    if flags and 'images' in flags:
+        for ilustr in document.edoc.findall('//ilustr'):
+            src = ilustr.get('src')
+            mime = ImageCover(src)().mime_type()
+            zip.write(src, os.path.join('OPS', src))
+            manifest.append(etree.fromstring(
+                '<item id="%s" href="%s" media-type="%s" />' % (src, src, mime)))
+            # get it up to master
+            after = ilustr
+            while after.getparent().tag not in ['powiesc', 'opowiadanie', 'liryka_l', 'liryka_lp', 'dramat_wierszowany_l', 'dramat_wierszowany_lp', 'dramat_wspolczesny']:
+                after = after.getparent()
+            if not(after is ilustr):
+                moved = deepcopy(ilustr)
+                ilustr.tag = 'extra'
+                ilustr.text = None
+                moved.tail = None
+                after.addnext(moved)
+    else:
+        for ilustr in document.edoc.findall('//ilustr'):
+            ilustr.tag = 'extra'
 
     annotations = etree.Element('annotations')
 
@@ -462,7 +490,13 @@ def transform(wldoc, verbose=False,
         '<item id="last" href="last.html" media-type="application/xhtml+xml" />'))
     spine.append(etree.fromstring(
         '<itemref idref="last" />'))
-    html_tree = xslt(document.edoc, get_resource('epub/xsltLast.xsl'))
+    stopka = document.edoc.find('//stopka')
+    if stopka is not None:
+        stopka.tag = 'stopka_'
+        replace_by_verse(stopka)
+        html_tree = xslt(stopka, get_resource('epub/xsltScheme.xsl'))
+    else:
+        html_tree = xslt(document.edoc, get_resource('epub/xsltLast.xsl'))
     chars.update(used_chars(html_tree.getroot()))
     zip.writestr('OPS/last.html', etree.tostring(
                         html_tree, method="html", pretty_print=True))
index 622c8da..a4c61c8 100644 (file)
@@ -46,7 +46,8 @@ a img {
 
 #book-text
 {
-       margin: 2em;
+       /*margin: 2em;*/
+    margin: 5px;
        /*margin-right: 9em;*/
 }
 
@@ -370,3 +371,12 @@ p.minor {
 p.footer {
     margin-top: 2em;
 }
+
+.ilustr {
+    margin-top: 1em;
+    margin-bottom: 1em;
+}
+
+.ilustr img {
+    max-width: 100%;
+}
index 83eb376..ef7ae74 100644 (file)
@@ -29,8 +29,6 @@
         <item id="toc" href="toc.ncx" media-type="application/x-dtbncx+xml" />
         <item id="style" href="style.css" media-type="text/css" />
         <item id="titlePage" href="title.html" media-type="application/xhtml+xml" />
-        <item id="logo_wolnelektury" href="logo_wolnelektury.png" media-type="image/png" />
-        <item id="jedenprocent" href="jedenprocent.png" media-type="image/png" />
       </manifest>
       <spine toc="toc">
         <itemref idref="titlePage" />
index 3ddcf97..395e950 100644 (file)
     <hr class="spacer-line" xmlns="http://www.w3.org/1999/xhtml"></hr>
   </xsl:template>
 
+  <xsl:template match="ilustr">
+    <div xmlns="http://www.w3.org/1999/xhtml" class="ilustr">
+      <img xmlns="http://www.w3.org/1999/xhtml" alt="ilustracja">
+        <xsl:attribute name="src">
+          <xsl:value-of select="@src" />
+        </xsl:attribute>
+      </img>
+    </div>
+  </xsl:template>
+
+  <xsl:template match="stopka" />
+
   <!--===========================================================-->
   <!-- Tagi SPECJALNE -->
   <!--===========================================================-->
index 74ef64a..0b926e2 100644 (file)
@@ -36,6 +36,7 @@
 
           <xsl:call-template name="translators" />
 
+      <xsl:if test="not(utwor/@not-wl)">
           <xsl:if test="not(utwor/@less-advertising)">
             <p class="info">
               <a>
           <p class="footer info">
             <a href="http://www.wolnelektury.pl/"><img src="logo_wolnelektury.png" alt="WolneLektury.pl" /></a>
           </p>
+      </xsl:if>
+      <!--xsl:if test="utwor/@not-wl">
+          <p class="info">
+            Konwersja wykonana przez<a href="http://www.nowoczesnapolska.org.pl/"> fundację Nowoczesna Polska</a>.
+          </p>
+      </xsl:if-->
         </div>
       </body>
     </html>
diff --git a/librarian/fonts/DroidSans.ttf b/librarian/fonts/DroidSans.ttf
new file mode 100644 (file)
index 0000000..2537cc3
Binary files /dev/null and b/librarian/fonts/DroidSans.ttf differ
diff --git a/librarian/fonts/EBGaramond-Regular.ttf b/librarian/fonts/EBGaramond-Regular.ttf
new file mode 100644 (file)
index 0000000..dde4869
Binary files /dev/null and b/librarian/fonts/EBGaramond-Regular.ttf differ
index 36a7b60..9a93e56 100644 (file)
@@ -63,6 +63,12 @@ class GandalfEpubPackager(EpubPackager):
 class GandalfPdfPackager(PdfPackager):
     cover = cover.GandalfCover
 
+class ArtaTechEpubPackager(EpubPackager):
+    cover = cover.ArtaTechCover
+
+class ArtaTechPdfPackager(PdfPackager):
+    cover = cover.ArtaTechCover
+
 class BookotekaEpubPackager(EpubPackager):
     cover = cover.BookotekaCover
 
diff --git a/librarian/res/cover-arta-tech.jpg b/librarian/res/cover-arta-tech.jpg
new file mode 100644 (file)
index 0000000..b69f469
Binary files /dev/null and b/librarian/res/cover-arta-tech.jpg differ
index bdb5ac6..ce8adb5 100755 (executable)
@@ -8,6 +8,7 @@ import os.path
 import optparse
 
 from librarian import DirDocProvider, ParseError
+from librarian.cover import ImageCover
 from librarian.parser import WLDocument
 
 
@@ -28,6 +29,14 @@ if __name__ == '__main__':
                       help='specifies the output file')
     parser.add_option('-O', '--output-dir', dest='output_dir', metavar='DIR',
                       help='specifies the directory for output')
+    parser.add_option('-i', '--with-images', action='store_true', dest='images', default=False,
+                      help='add images with <ilustr src="..."/>')
+    parser.add_option('-A', '--less-advertising', action='store_true', dest='less_advertising', default=False,
+                      help='less advertising, for commercial purposes')
+    parser.add_option('-W', '--not-wl', action='store_true', dest='not_wl', default=False,
+                      help='not a WolneLektury book')
+    parser.add_option('--cover', dest='cover', metavar='FILE',
+                      help='specifies the cover file')
 
     options, input_filenames = parser.parse_args()
 
@@ -49,7 +58,21 @@ if __name__ == '__main__':
                 output_file = None
 
             doc = WLDocument.from_file(main_input, provider=provider)
-            epub = doc.as_epub(cover=options.with_cover)
+
+            if options.cover:
+                cover = ImageCover(options.cover)
+            else:
+                cover = options.with_cover
+
+            flags = []
+            if options.images:
+                flags.append('images')
+            if options.less_advertising:
+                flags.append('less-advertising')
+            if options.not_wl:
+                flags.append('not-wl')
+
+            epub = doc.as_epub(cover=cover, flags=flags)
 
             doc.save_output_file(epub,
                 output_file, options.output_dir, options.make_dir, 'epub')
index 0488273..dcc8919 100755 (executable)
@@ -26,6 +26,10 @@ if __name__ == '__main__':
                       help='prepare EPUB files for Gandalf')
     parser.add_option('--gandalf-pdf', action='store_true', dest='gandalf_pdf', default=False,
                       help='prepare PDF files for Gandalf')
+    parser.add_option('--artatech', action='store_true', dest='artatech', default=False,
+                      help='prepare EPUB files for Arta-Tech')
+    parser.add_option('--artatech-pdf', action='store_true', dest='artatech_pdf', default=False,
+                      help='prepare PDF files for Arta-Tech')
     parser.add_option('--virtualo', action='store_true', dest='virtualo', default=False,
                       help='prepare files for Virtualo API')
     parser.add_option('--prestigio', action='store_true', dest='prestigio', default=False,
@@ -45,6 +49,10 @@ if __name__ == '__main__':
         packagers.GandalfEpubPackager.prepare(input_filenames, options.output_dir, options.verbose)
     if options.gandalf_pdf:
         packagers.GandalfPdfPackager.prepare(input_filenames, options.output_dir, options.verbose)
+    if options.artatech:
+        packagers.ArtaTechEpubPackager.prepare(input_filenames, options.output_dir, options.verbose)
+    if options.artatech_pdf:
+        packagers.ArtaTechPdfPackager.prepare(input_filenames, options.output_dir, options.verbose)
     if options.virtualo:
         packagers.VirtualoEpubPackager.prepare(input_filenames, options.output_dir, options.verbose)
     if options.prestigio: