mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
merge with bb:rolmei/sphinx-epub.
This commit is contained in:
commit
5fd37f16e4
@ -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
|
be an integer greater than zero. The default value is 3. Note: A deeply
|
||||||
nested table of contents may be difficult to navigate.
|
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:
|
.. _latex-options:
|
||||||
|
|
||||||
|
@ -11,13 +11,14 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import codecs
|
import codecs
|
||||||
from os import path
|
|
||||||
import zipfile
|
import zipfile
|
||||||
|
from os import path
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.transforms import Transform
|
|
||||||
|
|
||||||
|
from sphinx import addnodes
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
from sphinx.util.osutil import EEXIST
|
from sphinx.util.osutil import EEXIST
|
||||||
from sphinx.util.smartypants import sphinx_smarty_pants as ssp
|
from sphinx.util.smartypants import sphinx_smarty_pants as ssp
|
||||||
@ -120,29 +121,10 @@ _media_types = {
|
|||||||
'.ttf': 'application/x-font-ttf',
|
'.ttf': 'application/x-font-ttf',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Regular expression to match colons only in local fragment identifiers.
|
||||||
# The transform to show link targets
|
# If the URI contains a colon before the #,
|
||||||
|
# it is an external link that should not change.
|
||||||
class VisibleLinksTransform(Transform):
|
_refuri_re = re.compile("([^#:]*#)(.*)")
|
||||||
"""
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
# The epub publisher
|
# The epub publisher
|
||||||
@ -171,10 +153,6 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
# the output files for epub must be .html only
|
# the output files for epub must be .html only
|
||||||
self.out_suffix = '.html'
|
self.out_suffix = '.html'
|
||||||
self.playorder = 0
|
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):
|
def get_theme_config(self):
|
||||||
return self.config.epub_theme, {}
|
return self.config.epub_theme, {}
|
||||||
@ -198,7 +176,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
"""Collect section titles, their depth in the toc and the refuri."""
|
"""Collect section titles, their depth in the toc and the refuri."""
|
||||||
# XXX: is there a better way than checking the attribute
|
# XXX: is there a better way than checking the attribute
|
||||||
# toctree-l[1-8] on the parent node?
|
# 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']
|
refuri = doctree['refuri']
|
||||||
if refuri.startswith('http://') or refuri.startswith('https://') \
|
if refuri.startswith('http://') or refuri.startswith('https://') \
|
||||||
or refuri.startswith('irc:') or refuri.startswith('mailto:'):
|
or refuri.startswith('irc:') or refuri.startswith('mailto:'):
|
||||||
@ -243,6 +221,81 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
'text': ssp(self.esc(text))
|
'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
|
# Finish by building the epub file
|
||||||
def handle_finish(self):
|
def handle_finish(self):
|
||||||
@ -388,7 +441,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
navstack.append(navlist)
|
navstack.append(navlist)
|
||||||
navlist = []
|
navlist = []
|
||||||
level += 1
|
level += 1
|
||||||
if lastnode:
|
if lastnode and self.config.epub_tocdup:
|
||||||
# Insert starting point in subtoc with same playOrder
|
# Insert starting point in subtoc with same playOrder
|
||||||
navlist.append(self.new_navpoint(lastnode, level, False))
|
navlist.append(self.new_navpoint(lastnode, level, False))
|
||||||
navlist.append(self.new_navpoint(node, level))
|
navlist.append(self.new_navpoint(node, level))
|
||||||
|
@ -124,6 +124,7 @@ class Config(object):
|
|||||||
epub_post_files = ([], 'env'),
|
epub_post_files = ([], 'env'),
|
||||||
epub_exclude_files = ([], 'env'),
|
epub_exclude_files = ([], 'env'),
|
||||||
epub_tocdepth = (3, 'env'),
|
epub_tocdepth = (3, 'env'),
|
||||||
|
epub_tocdup = (True, 'env'),
|
||||||
|
|
||||||
# LaTeX options
|
# LaTeX options
|
||||||
latex_documents = ([], None),
|
latex_documents = ([], None),
|
||||||
|
@ -279,6 +279,9 @@ epub_copyright = u'%(copyright_str)s'
|
|||||||
|
|
||||||
# The depth of the table of contents in toc.ncx.
|
# The depth of the table of contents in toc.ncx.
|
||||||
#epub_tocdepth = 3
|
#epub_tocdepth = 3
|
||||||
|
|
||||||
|
# Allow duplicate toc entries.
|
||||||
|
#epub_tocdup = True
|
||||||
'''
|
'''
|
||||||
|
|
||||||
INTERSPHINX_CONFIG = '''
|
INTERSPHINX_CONFIG = '''
|
||||||
|
Loading…
Reference in New Issue
Block a user