merge with bb:rolmei/sphinx-epub.

This commit is contained in:
Georg Brandl 2010-07-22 15:04:22 +01:00
commit 5fd37f16e4
4 changed files with 94 additions and 31 deletions

View File

@ -782,6 +782,12 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
be an integer greater than zero. The default value is 3. Note: A deeply
nested table of contents may be difficult to navigate.
.. confval:: epub_tocdup
This flag determines if a toc entry is inserted again at the beginning of
it's nested toc listing. This allows easier navitation to the top of
a chapter, but can be confusing because it mixes entries of differnet
depth in one list. The default value is ``True``.
.. _latex-options:

View File

@ -11,13 +11,14 @@
"""
import os
import re
import codecs
from os import path
import zipfile
from os import path
from docutils import nodes
from docutils.transforms import Transform
from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util.osutil import EEXIST
from sphinx.util.smartypants import sphinx_smarty_pants as ssp
@ -120,29 +121,10 @@ _media_types = {
'.ttf': 'application/x-font-ttf',
}
# The transform to show link targets
class VisibleLinksTransform(Transform):
"""
Add the link target of references to the text, unless it is already
present in the description.
"""
# This transform must run after the references transforms
default_priority = 680
def apply(self):
for ref in self.document.traverse(nodes.reference):
uri = ref.get('refuri', '')
if ( uri.startswith('http:') or uri.startswith('https:') or \
uri.startswith('ftp:') ) and uri not in ref.astext():
uri = _link_target_template % {'uri': uri}
if uri:
idx = ref.parent.index(ref) + 1
link = nodes.inline(uri, uri)
link['classes'].append(_css_link_target_class)
ref.parent.insert(idx, link)
# Regular expression to match colons only in local fragment identifiers.
# If the URI contains a colon before the #,
# it is an external link that should not change.
_refuri_re = re.compile("([^#:]*#)(.*)")
# The epub publisher
@ -171,10 +153,6 @@ class EpubBuilder(StandaloneHTMLBuilder):
# the output files for epub must be .html only
self.out_suffix = '.html'
self.playorder = 0
# Disable transform until the issue with cached doctrees is solved.
# Building the html file after the epub file shows the
# visible links also in the HTML output.
#self.app.add_transform(VisibleLinksTransform)
def get_theme_config(self):
return self.config.epub_theme, {}
@ -198,7 +176,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
"""Collect section titles, their depth in the toc and the refuri."""
# XXX: is there a better way than checking the attribute
# toctree-l[1-8] on the parent node?
if isinstance(doctree, nodes.reference) and hasattr(doctree, 'refuri'):
if isinstance(doctree, nodes.reference) and doctree.has_key('refuri'):
refuri = doctree['refuri']
if refuri.startswith('http://') or refuri.startswith('https://') \
or refuri.startswith('irc:') or refuri.startswith('mailto:'):
@ -243,6 +221,81 @@ class EpubBuilder(StandaloneHTMLBuilder):
'text': ssp(self.esc(text))
})
def fix_fragment(self, match):
"""Return a href attribute with colons replaced by hyphens.
"""
return match.group(1) + match.group(2).replace(':', '-')
def fix_ids(self, tree):
"""Replace colons with hyphens in href and id attributes.
Some readers crash because they interpret the part as a
transport protocol specification.
"""
for node in tree.traverse(nodes.reference):
if 'refuri' in node:
m = _refuri_re.match(node['refuri'])
if m:
node['refuri'] = self.fix_fragment(m)
if 'refid' in node:
node['refid'] = node['refid'].replace(':', '-')
for node in tree.traverse(addnodes.desc_signature):
ids = node.attributes['ids']
newids = []
for id in ids:
newids.append(id.replace(':', '-'))
node.attributes['ids'] = newids
def add_visible_links(self, tree):
"""Append visible link targets after external links.
"""
for node in tree.traverse(nodes.reference):
uri = node.get('refuri', '')
if (uri.startswith('http:') or uri.startswith('https:') or
uri.startswith('ftp:')) and uri not in node.astext():
uri = _link_target_template % {'uri': uri}
if uri:
idx = node.parent.index(node) + 1
link = nodes.inline(uri, uri)
link['classes'].append(_css_link_target_class)
node.parent.insert(idx, link)
def write_doc(self, docname, doctree):
"""Write one document file.
This method is overwritten in order to fix fragment identifiers
and to add visible external links.
"""
self.fix_ids(doctree)
self.add_visible_links(doctree)
return StandaloneHTMLBuilder.write_doc(self, docname, doctree)
def fix_genindex(self, tree):
"""Fix href attributes for genindex pages.
"""
# XXX: modifies tree inline
# Logic modeled from themes/basic/genindex.html
for key, columns in tree:
for entryname, (links, subitems) in columns:
for (i, link) in enumerate(links):
m = _refuri_re.match(link)
if m:
links[i] = self.fix_fragment(m)
for subentryname, subentrylinks in subitems:
for (i, link) in enumerate(subentrylinks):
m = _refuri_re.match(link)
if m:
subentrylinks[i] = self.fix_fragment(m)
def handle_page(self, pagename, addctx, templatename='page.html',
outfilename=None, event_arg=None):
"""Create a rendered page.
This method is overwritten for genindex pages in order to fix
href link attributes.
"""
if pagename.startswith('genindex'):
self.fix_genindex(addctx['genindexentries'])
StandaloneHTMLBuilder.handle_page(self, pagename, addctx, templatename,
outfilename, event_arg)
# Finish by building the epub file
def handle_finish(self):
@ -388,7 +441,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
navstack.append(navlist)
navlist = []
level += 1
if lastnode:
if lastnode and self.config.epub_tocdup:
# Insert starting point in subtoc with same playOrder
navlist.append(self.new_navpoint(lastnode, level, False))
navlist.append(self.new_navpoint(node, level))

View File

@ -124,6 +124,7 @@ class Config(object):
epub_post_files = ([], 'env'),
epub_exclude_files = ([], 'env'),
epub_tocdepth = (3, 'env'),
epub_tocdup = (True, 'env'),
# LaTeX options
latex_documents = ([], None),

View File

@ -279,6 +279,9 @@ epub_copyright = u'%(copyright_str)s'
# The depth of the table of contents in toc.ncx.
#epub_tocdepth = 3
# Allow duplicate toc entries.
#epub_tocdup = True
'''
INTERSPHINX_CONFIG = '''