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
# 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,
background_color = '#fff'
background_img = None
+ author_align = 'c'
author_top = 100
author_margin_left = 20
author_margin_right = 20
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
title_color = '#000'
title_shadow = None
title_font = None
+ title_wrap = True
logo_bottom = None
logo_width = None
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
)
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)
)
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)
bar_width = 35
background_color = '#444'
author_color = '#444'
+ default_background = get_resource('res/cover.png')
+ format = 'JPEG'
epochs = {
u'Starożytność': 0,
bg_src = urlopen(book_info.cover_url)
self.background_img = StringIO(bg_src.read())
bg_src.close()
+ else:
+ self.background_img = self.default_background
def pretty_author(self):
return self.author.upper()
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
class GandalfPdfPackager(PdfPackager):
cover = cover.GandalfCover
+class ArtaTechEpubPackager(EpubPackager):
+ cover = cover.ArtaTechCover
+
+class ArtaTechPdfPackager(PdfPackager):
+ cover = cover.ArtaTechCover
+
class BookotekaEpubPackager(EpubPackager):
cover = cover.BookotekaCover
flags = ('less-advertising',)
- class VirtualoEpubPackager(Packager):
+ class VirtualoPackager(Packager):
@staticmethod
def utf_trunc(text, limit):
""" truncates text to at most `limit' bytes in utf-8 """
cover.VirtualoCover(info).save(os.path.join(outfile_dir, slug+'.jpg'))
outfile = os.path.join(outfile_dir, '1.epub')
outfile_sample = os.path.join(outfile_dir, '1.sample.epub')
- doc.save_output_file(epub.transform(doc),
+ doc.save_output_file(doc.as_epub(),
output_path=outfile)
- doc.save_output_file(epub.transform(doc, sample=25),
+ doc.save_output_file(doc.as_epub(doc, sample=25),
+ output_path=outfile_sample)
+ outfile = os.path.join(outfile_dir, '1.mobi')
+ outfile_sample = os.path.join(outfile_dir, '1.sample.mobi')
+ doc.save_output_file(doc.as_mobi(cover=cover.VirtualoCover),
+ output_path=outfile)
+ doc.save_output_file(
+ doc.as_mobi(doc, cover=cover.VirtualoCover, sample=25),
output_path=outfile_sample)
except ParseError, e:
print '%(file)s:%(name)s:%(message)s' % {
xmlns:dc="http://purl.org/dc/elements/1.1/" >
<xsl:output encoding="utf-8" indent="yes" omit-xml-declaration = "yes" version="2.0" />
+ <xsl:strip-space elements="opowiadanie powiesc dramat_wierszowany_l dramat_wierszowany_lp dramat_wspolczesny liryka_l liryka_lp wywiad"/>
<xsl:template match="utwor">
<xsl:choose>
<xsl:when test="@full-page">
<html>
<head>
- <title>Książka z serwisu WolneLektury.pl</title>
+ <title><xsl:apply-templates mode="inline" select="//nazwa_utworu" /></title>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
</head>
<style>
img {
border: none;
+ max-width: 100%;
}
<!-- Section headers (included in index)-->
<xsl:template match="naglowek_akt|naglowek_czesc|srodtytul">
+ <xsl:call-template name="section-anchor"/>
<h2><xsl:apply-templates mode="inline" /></h2>
</xsl:template>
<xsl:template match="naglowek_scena|naglowek_rozdzial">
+ <xsl:call-template name="section-anchor"/>
<h3><xsl:apply-templates mode="inline" /></h3>
</xsl:template>
<xsl:template match="naglowek_osoba|naglowek_podrozdzial">
+ <xsl:call-template name="section-anchor"/>
<h4><xsl:apply-templates mode="inline" /></h4>
</xsl:template>
<!-- Other paragraph tags -->
<xsl:template match="miejsce_czas">
+ <xsl:call-template name="section-anchor"/>
<p class="place-and-time"><xsl:apply-templates mode="inline" /></p>
</xsl:template>
<xsl:template match="didaskalia">
+ <xsl:call-template name="section-anchor"/>
<div class="didaskalia"><xsl:apply-templates mode="inline" /></div>
</xsl:template>
</xsl:template>
<xsl:template match="akap|akap_dialog|akap_cd">
- <p class="paragraph"><xsl:apply-templates mode="inline" /></p>
+ <p class="paragraph">
+ <xsl:call-template name="section-anchor"/>
+ <xsl:apply-templates mode="inline" />
+ </p>
</xsl:template>
<xsl:template match="strofa">
<div class="stanza">
+ <xsl:call-template name="section-anchor"/>
<xsl:choose>
<xsl:when test="count(br) > 0">
<xsl:call-template name="verse">
<hr class="spacer-line" />
</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>
+ <xsl:attribute name="alt">
+ <xsl:apply-templates mode="inline" />
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:apply-templates mode="inline" />
+ </xsl:attribute>
+ </img>
+ </div>
+</xsl:template>
+
<!-- ================ -->
<!-- = SPECIAL TAGS = -->
<xsl:value-of select="wl:substitute_entities(.)" />
</xsl:template>
+ <!-- ========= -->
+ <!-- = utils = -->
+ <!-- ========= -->
+ <xsl:template name="section-anchor">
+ <!--
+ this formula works as follows:
+ - get all ancestors including self
+ - choose the header (third one from root): utwor/book-type/header
+ - get all preceding siblings
+ - count them
+ - create an <a name="sec123"/> tag.
+ -->
+ <a name="{concat('sec', count(ancestor-or-self::*[last()-2]/preceding-sibling::*) + 1)}" />
+ </xsl:template>
- </xsl:stylesheet>
+ </xsl:stylesheet>
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,
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)
+ packagers.VirtualoPackager.prepare(input_filenames, options.output_dir, options.verbose)
if options.prestigio:
packagers.PrestigioEpubPackager.prepare(input_filenames, options.output_dir, options.verbose)
if options.prestigio_pdf: