summaryrefslogtreecommitdiff
path: root/sphinx/builders/epub.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/builders/epub.py')
-rw-r--r--sphinx/builders/epub.py73
1 files changed, 68 insertions, 5 deletions
diff --git a/sphinx/builders/epub.py b/sphinx/builders/epub.py
index e946e0d3..ad990615 100644
--- a/sphinx/builders/epub.py
+++ b/sphinx/builders/epub.py
@@ -18,12 +18,21 @@ import codecs
import zipfile
from os import path
+try:
+ from PIL import Image
+except ImportError:
+ try:
+ import Image
+ except ImportError:
+ Image = None
+
from docutils import nodes
from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder
-from sphinx.util.osutil import EEXIST
+from sphinx.util.osutil import ensuredir, EEXIST
from sphinx.util.smartypants import sphinx_smarty_pants as ssp
+from sphinx.util.console import brown
# (Fragment) templates from which the metainfo files content.opf, toc.ncx,
@@ -165,7 +174,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
self.playorder = 0
def get_theme_config(self):
- return self.config.epub_theme, {}
+ return self.config.epub_theme, self.config.epub_theme_options
# generic support functions
def make_id(self, name):
@@ -206,11 +215,11 @@ class EpubBuilder(StandaloneHTMLBuilder):
return result
def get_toc(self):
- """Get the total table of contents, containg the master_doc
+ """Get the total table of contents, containing the master_doc
and pre and post files not managed by sphinx.
"""
doctree = self.env.get_and_resolve_doctree(self.config.master_doc,
- self, prune_toctrees=False)
+ self, prune_toctrees=False, includehidden=True)
self.refnodes = self.get_refnodes(doctree, [])
master_dir = os.path.dirname(self.config.master_doc)
if master_dir:
@@ -301,6 +310,57 @@ class EpubBuilder(StandaloneHTMLBuilder):
subentrylinks[i] = (ismain,
self.fix_fragment(m.group(1), m.group(2)))
+ def copy_image_files_pil(self):
+ """Copy images using the PIL.
+ The method tries to read and write the files with the PIL,
+ converting the format and resizing the image if necessary/possible.
+ """
+ ensuredir(path.join(self.outdir, '_images'))
+ for src in self.status_iterator(self.images, 'copying images... ',
+ brown, len(self.images)):
+ dest = self.images[src]
+ try:
+ img = Image.open(path.join(self.srcdir, src))
+ except IOError:
+ self.warn('cannot read image file %r: copying it instead' %
+ (path.join(self.srcdir, src), ))
+ try:
+ copyfile(path.join(self.srcdir, src),
+ path.join(self.outdir, '_images', dest))
+ except Exception, err:
+ self.warn('cannot copy image file %r: %s' %
+ (path.join(self.srcdir, src), err))
+ continue
+ if self.config.epub_fix_images:
+ if img.mode in ('P',):
+ # See PIL documentation for Image.convert()
+ img = img.convert()
+ if self.config.epub_max_image_width > 0:
+ (width, height) = img.size
+ nw = self.config.epub_max_image_width
+ if width > nw:
+ nh = (height * nw) / width
+ img = img.resize((nw, nh), Image.BICUBIC)
+ try:
+ img.save(path.join(self.outdir, '_images', dest))
+ except IOError, err:
+ self.warn('cannot write image file %r: %s' %
+ (path.join(self.srcdir, src), err))
+
+ def copy_image_files(self):
+ """Copy image files to destination directory.
+ This overwritten method can use the PIL to convert image files.
+ """
+ if self.images:
+ if self.config.epub_fix_images or self.config.epub_max_image_width:
+ if not Image:
+ self.warn('PIL not found - copying image files')
+ super(EpubBuilder, self).copy_image_files()
+ else:
+ self.copy_image_files_pil()
+ else:
+ super(EpubBuilder, self).copy_image_files()
+
def handle_page(self, pagename, addctx, templatename='page.html',
outfilename=None, event_arg=None):
"""Create a rendered page.
@@ -529,7 +589,10 @@ class EpubBuilder(StandaloneHTMLBuilder):
"""Write the metainfo file toc.ncx."""
self.info('writing %s file...' % outname)
- navpoints = self.build_navpoints(self.refnodes)
+ doctree = self.env.get_and_resolve_doctree(self.config.master_doc,
+ self, prune_toctrees=False, includehidden=False)
+ refnodes = self.get_refnodes(doctree, [])
+ navpoints = self.build_navpoints(refnodes)
level = max(item['level'] for item in self.refnodes)
level = min(level, self.config.epub_tocdepth)
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')