Merged in rolmei/sphinx-epub (pull request #56)

This commit is contained in:
Georg Brandl 2012-04-11 21:35:35 +02:00
commit 9af2094ca4
6 changed files with 72 additions and 6 deletions

View File

@ -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 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 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 details about it. For definition of the epub format, have a look at
`<http://www.idpf.org/specs.htm>`_ or `<http://en.wikipedia.org/wiki/EPUB>`_. `<http://idpf.org/epub>`_ or `<http://en.wikipedia.org/wiki/EPUB>`_.
The builder creates *EPUB 2* files.
Some ebook readers do not show the link targets of references. Therefore Some ebook readers do not show the link targets of references. Therefore
this builder adds the targets after the link when necessary. The display this builder adds the targets after the link when necessary. The display

View File

@ -854,6 +854,20 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
.. versionadded:: 1.1 .. 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 `<http://idpf.org/epub>`_ 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 .. confval:: epub_pre_files
Additional files that should be inserted before the text generated by Additional files that should be inserted before the text generated by

View File

@ -104,6 +104,9 @@ _content_template = u'''\
<spine toc="ncx"> <spine toc="ncx">
%(spine)s %(spine)s
</spine> </spine>
<guide>
%(guide)s
</guide>
</package> </package>
''' '''
@ -121,12 +124,21 @@ _file_template = u'''\
_spine_template = u'''\ _spine_template = u'''\
<itemref idref="%(idref)s" />''' <itemref idref="%(idref)s" />'''
_guide_template = u'''\
<reference type="%(type)s" title="%(title)s" href="%(uri)s" />'''
_toctree_template = u'toctree-l%d' _toctree_template = u'toctree-l%d'
_link_target_template = u' [%(uri)s]' _link_target_template = u' [%(uri)s]'
_css_link_target_class = u'link-target' _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 = { _media_types = {
'.html': 'application/xhtml+xml', '.html': 'application/xhtml+xml',
'.css': 'text/css', '.css': 'text/css',
@ -408,7 +420,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
finally: finally:
f.close() 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 """Create a dictionary with all metadata for the content.opf
file properly escaped. file properly escaped.
""" """
@ -424,6 +436,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
metadata['date'] = self.esc(time.strftime('%Y-%m-%d')) metadata['date'] = self.esc(time.strftime('%Y-%m-%d'))
metadata['files'] = files metadata['files'] = files
metadata['spine'] = spine metadata['spine'] = spine
metadata['guide'] = guide
return metadata return metadata
def build_content(self, outdir, outname): def build_content(self, outdir, outname):
@ -479,14 +492,15 @@ class EpubBuilder(StandaloneHTMLBuilder):
# add the optional cover # add the optional cover
content_tmpl = _content_template content_tmpl = _content_template
html_tmpl = None
if self.config.epub_cover: if self.config.epub_cover:
image, tmpl = self.config.epub_cover image, html_tmpl = self.config.epub_cover
mpos = content_tmpl.rfind('</metadata>') mpos = content_tmpl.rfind('</metadata>')
cpos = content_tmpl.rfind('\n', 0 , mpos) + 1 cpos = content_tmpl.rfind('\n', 0 , mpos) + 1
content_tmpl = content_tmpl[:cpos] + \ content_tmpl = content_tmpl[:cpos] + \
_cover_template % {'cover': self.esc(self.make_id(image))} + \ _cover_template % {'cover': self.esc(self.make_id(image))} + \
content_tmpl[cpos:] content_tmpl[cpos:]
if tmpl: if html_tmpl:
spine.insert(0, _spine_template % { spine.insert(0, _spine_template % {
'idref': self.esc(self.make_id(_coverpage_name))}) 'idref': self.esc(self.make_id(_coverpage_name))})
if _coverpage_name not in self.files: if _coverpage_name not in self.files:
@ -499,16 +513,46 @@ class EpubBuilder(StandaloneHTMLBuilder):
}) })
ctx = {'image': self.esc(image), 'title': self.config.project} ctx = {'image': self.esc(image), 'title': self.config.project}
self.handle_page( 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) projectfiles = '\n'.join(projectfiles)
spine = '\n'.join(spine) spine = '\n'.join(spine)
guide = '\n'.join(guide)
# write the project file # write the project file
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8') f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
try: try:
f.write(content_tmpl % \ f.write(content_tmpl % \
self.content_metadata(projectfiles, spine)) self.content_metadata(projectfiles, spine, guide))
finally: finally:
f.close() f.close()
@ -592,6 +636,8 @@ class EpubBuilder(StandaloneHTMLBuilder):
doctree = self.env.get_and_resolve_doctree(self.config.master_doc, doctree = self.env.get_and_resolve_doctree(self.config.master_doc,
self, prune_toctrees=False, includehidden=False) self, prune_toctrees=False, includehidden=False)
refnodes = self.get_refnodes(doctree, []) refnodes = self.get_refnodes(doctree, [])
if not refnodes:
refnodes = self.refnodes
navpoints = self.build_navpoints(refnodes) navpoints = self.build_navpoints(refnodes)
level = max(item['level'] for item in self.refnodes) level = max(item['level'] for item in self.refnodes)
level = min(level, self.config.epub_tocdepth) level = min(level, self.config.epub_tocdepth)

View File

@ -133,6 +133,7 @@ class Config(object):
epub_scheme = ('unknown', 'html'), epub_scheme = ('unknown', 'html'),
epub_uid = ('unknown', 'env'), epub_uid = ('unknown', 'env'),
epub_cover = ((), 'env'), epub_cover = ((), 'env'),
epub_guide = ((), 'env'),
epub_pre_files = ([], 'env'), epub_pre_files = ([], 'env'),
epub_post_files = ([], 'env'), epub_post_files = ([], 'env'),
epub_exclude_files = ([], 'env'), epub_exclude_files = ([], 'env'),

View File

@ -309,6 +309,9 @@ epub_copyright = u'%(copyright_str)s'
# A tuple containing the cover image and cover page html template filenames. # A tuple containing the cover image and cover page html template filenames.
#epub_cover = () #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. # HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title. # The format is a list of tuples containing the path and title.
#epub_pre_files = [] #epub_pre_files = []

View File

@ -8,6 +8,7 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
#} #}
{% extends "layout.html" %} {% extends "layout.html" %}
{%- block header %}{% endblock %}
{%- block rootrellink %}{% endblock %} {%- block rootrellink %}{% endblock %}
{%- block relbaritems %}{% endblock %} {%- block relbaritems %}{% endblock %}
{%- block sidebarlogo %}{% endblock %} {%- block sidebarlogo %}{% endblock %}