diff --git a/doc/builders.rst b/doc/builders.rst index 71600137d..6600807d3 100644 --- a/doc/builders.rst +++ b/doc/builders.rst @@ -81,7 +81,8 @@ The builder's "name" must be given to the **-b** command-line option of This builder produces the same output as the standalone HTML builder, but also generates an *epub* file for ebook readers. See :ref:`epub-faq` for details about it. For definition of the epub format, have a look at - ``_ or ``_. + ``_ or ``_. + The builder creates *EPUB 2* files. Some ebook readers do not show the link targets of references. Therefore this builder adds the targets after the link when necessary. The display diff --git a/doc/config.rst b/doc/config.rst index a8d5c07f2..6178d459b 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -854,6 +854,20 @@ the `Dublin Core metadata `_. .. versionadded:: 1.1 +.. confval:: epub_guide + + Meta data for the guide element of :file:`content.opf`. This is a + sequence of tuples containing the *type*, the *uri* and the *title* of + the optional guide information. See the OPF documentation + at ``_ for details. If possible, default entries + for the *cover* and *toc* types are automatically inserted. However, + the types can be explicitely overwritten if the default entries are not + appropriate. Example:: + + epub_guide = (('cover', 'cover.html', u'Cover Page'),) + + The default value is ``()``. + .. confval:: epub_pre_files Additional files that should be inserted before the text generated by diff --git a/sphinx/builders/epub.py b/sphinx/builders/epub.py index ad9906155..b4c3b2776 100644 --- a/sphinx/builders/epub.py +++ b/sphinx/builders/epub.py @@ -104,6 +104,9 @@ _content_template = u'''\ %(spine)s + +%(guide)s + ''' @@ -121,12 +124,21 @@ _file_template = u'''\ _spine_template = u'''\ ''' +_guide_template = u'''\ + ''' + _toctree_template = u'toctree-l%d' _link_target_template = u' [%(uri)s]' _css_link_target_class = u'link-target' +# XXX These strings should be localized according to epub_language +_guide_titles = { + 'toc': u'Table of Contents', + 'cover': u'Cover Page' +} + _media_types = { '.html': 'application/xhtml+xml', '.css': 'text/css', @@ -408,7 +420,7 @@ class EpubBuilder(StandaloneHTMLBuilder): finally: f.close() - def content_metadata(self, files, spine): + def content_metadata(self, files, spine, guide): """Create a dictionary with all metadata for the content.opf file properly escaped. """ @@ -424,6 +436,7 @@ class EpubBuilder(StandaloneHTMLBuilder): metadata['date'] = self.esc(time.strftime('%Y-%m-%d')) metadata['files'] = files metadata['spine'] = spine + metadata['guide'] = guide return metadata def build_content(self, outdir, outname): @@ -479,14 +492,15 @@ class EpubBuilder(StandaloneHTMLBuilder): # add the optional cover content_tmpl = _content_template + html_tmpl = None if self.config.epub_cover: - image, tmpl = self.config.epub_cover + image, html_tmpl = self.config.epub_cover mpos = content_tmpl.rfind('') cpos = content_tmpl.rfind('\n', 0 , mpos) + 1 content_tmpl = content_tmpl[:cpos] + \ _cover_template % {'cover': self.esc(self.make_id(image))} + \ content_tmpl[cpos:] - if tmpl: + if html_tmpl: spine.insert(0, _spine_template % { 'idref': self.esc(self.make_id(_coverpage_name))}) if _coverpage_name not in self.files: @@ -499,16 +513,46 @@ class EpubBuilder(StandaloneHTMLBuilder): }) ctx = {'image': self.esc(image), 'title': self.config.project} self.handle_page( - os.path.splitext(_coverpage_name)[0], ctx, tmpl) + os.path.splitext(_coverpage_name)[0], ctx, html_tmpl) + guide = [] + auto_add_cover = True + auto_add_toc = True + if self.config.epub_guide: + for type, uri, title in self.config.epub_guide: + file = uri.split('#')[0] + if file not in self.files: + self.files.append(file) + if type == 'cover': + auto_add_cover = False + if type == 'toc': + auto_add_toc = False + guide.append(_guide_template % { + 'type': self.esc(type), + 'title': self.esc(title), + 'uri': self.esc(uri) + }) + if auto_add_cover and html_tmpl: + guide.append(_guide_template % { + 'type': 'cover', + 'title': _guide_titles['cover'], + 'uri': self.esc(_coverpage_name) + }) + if auto_add_toc and self.refnodes: + guide.append(_guide_template % { + 'type': 'toc', + 'title': _guide_titles['toc'], + 'uri': self.esc(self.refnodes[0]['refuri']) + }) projectfiles = '\n'.join(projectfiles) spine = '\n'.join(spine) + guide = '\n'.join(guide) # write the project file f = codecs.open(path.join(outdir, outname), 'w', 'utf-8') try: f.write(content_tmpl % \ - self.content_metadata(projectfiles, spine)) + self.content_metadata(projectfiles, spine, guide)) finally: f.close() @@ -592,6 +636,8 @@ class EpubBuilder(StandaloneHTMLBuilder): doctree = self.env.get_and_resolve_doctree(self.config.master_doc, self, prune_toctrees=False, includehidden=False) refnodes = self.get_refnodes(doctree, []) + if not refnodes: + refnodes = self.refnodes navpoints = self.build_navpoints(refnodes) level = max(item['level'] for item in self.refnodes) level = min(level, self.config.epub_tocdepth) diff --git a/sphinx/config.py b/sphinx/config.py index 8da81361a..2012634e1 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -133,6 +133,7 @@ class Config(object): epub_scheme = ('unknown', 'html'), epub_uid = ('unknown', 'env'), epub_cover = ((), 'env'), + epub_guide = ((), 'env'), epub_pre_files = ([], 'env'), epub_post_files = ([], 'env'), epub_exclude_files = ([], 'env'), diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index 172382ad5..c8dd2579c 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -309,6 +309,9 @@ epub_copyright = u'%(copyright_str)s' # A tuple containing the cover image and cover page html template filenames. #epub_cover = () +# A sequence of (type, uri, title) tuples for the guide element of content.opf. +#epub_guide = () + # HTML files that should be inserted before the pages created by sphinx. # The format is a list of tuples containing the path and title. #epub_pre_files = [] diff --git a/sphinx/themes/epub/epub-cover.html b/sphinx/themes/epub/epub-cover.html index f80889250..b3202a33f 100644 --- a/sphinx/themes/epub/epub-cover.html +++ b/sphinx/themes/epub/epub-cover.html @@ -8,6 +8,7 @@ :license: BSD, see LICENSE for details. #} {% extends "layout.html" %} +{%- block header %}{% endblock %} {%- block rootrellink %}{% endblock %} {%- block relbaritems %}{% endblock %} {%- block sidebarlogo %}{% endblock %}