diff options
| author | Georg Brandl <georg@python.org> | 2010-02-19 10:20:07 +0100 |
|---|---|---|
| committer | Georg Brandl <georg@python.org> | 2010-02-19 10:20:07 +0100 |
| commit | dece20e57b61cf475c6ac52acea17dd7c6ef772f (patch) | |
| tree | e407e2b99fcc5990516eb93f77ce521f4d0c3923 | |
| parent | dd1d2974e9329db35ae8afbc75ca8e1ca25c6b80 (diff) | |
| parent | f10c5bc3134febfa3f37537880884926e388a30e (diff) | |
| download | sphinx-dece20e57b61cf475c6ac52acea17dd7c6ef772f.tar.gz | |
merge with http://bitbucket.org/rolmei/sphinx-epub/.
| -rw-r--r-- | doc/builders.rst | 5 | ||||
| -rw-r--r-- | doc/config.rst | 6 | ||||
| -rw-r--r-- | sphinx/builders/epub.py | 73 | ||||
| -rw-r--r-- | sphinx/config.py | 1 | ||||
| -rw-r--r-- | sphinx/quickstart.py | 3 | ||||
| -rw-r--r-- | sphinx/themes/epub/static/epub.css | 13 |
6 files changed, 74 insertions, 27 deletions
diff --git a/doc/builders.rst b/doc/builders.rst index 1c2bd39f..1c207574 100644 --- a/doc/builders.rst +++ b/doc/builders.rst @@ -81,6 +81,11 @@ The builder's "name" must be given to the **-b** command-line option of 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>`_. + Some ebook readers do not show the link targets of references. Therefore + this builder adds the targets after the link when necessary. The display + of the URLs can be customized by adding CSS rules for the class + ``link-target``. + Its name is ``epub``. .. module:: sphinx.builders.latex diff --git a/doc/config.rst b/doc/config.rst index 92542f8c..979bc8f0 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -708,6 +708,12 @@ the `Dublin Core metadata <http://dublincore.org/>`_. A list of files that are generated/copied in the build directory but should not be included in the epub file. The default value is ``[]``. +.. confval:: epub_tocdepth + + The depth of the table of contents in the file :file:`toc.ncx`. It should + be an integer greater than zero. The default value is 3. Note: A deeply + nested table of contents may be difficult to navigate. + .. _latex-options: diff --git a/sphinx/builders/epub.py b/sphinx/builders/epub.py index 6694c8af..9767391e 100644 --- a/sphinx/builders/epub.py +++ b/sphinx/builders/epub.py @@ -16,6 +16,7 @@ from os import path import zipfile from docutils import nodes +from docutils.transforms import Transform from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.util.osutil import EEXIST @@ -23,6 +24,9 @@ from sphinx.util.osutil import EEXIST # (Fragment) templates from which the metainfo files content.opf, toc.ncx, # mimetype, and META-INF/container.xml are created. +# This template section also defines strings that are embedded in the html +# output but that may be customized by (re-)setting module attributes, +# e.g. from conf.py. _mimetype_template = 'application/epub+zip' # no EOL! @@ -99,6 +103,10 @@ _spine_template = u'''\ _toctree_template = u'toctree-l%d' +_link_target_template = u' [%(uri)s]' + +_css_link_target_class = u'link-target' + _media_types = { '.html': 'application/xhtml+xml', '.css': 'text/css', @@ -112,6 +120,30 @@ _media_types = { } +# The transform to show link targets + +class VisibleLinksTransform(Transform): + """ + Add the link target of referances 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 class EpubBuilder(StandaloneHTMLBuilder): @@ -138,6 +170,7 @@ class EpubBuilder(StandaloneHTMLBuilder): # the output files for epub must be .html only self.out_suffix = '.html' self.playorder = 0 + self.app.add_transform(VisibleLinksTransform) def get_theme_config(self): return self.config.epub_theme, {} @@ -145,7 +178,7 @@ class EpubBuilder(StandaloneHTMLBuilder): # generic support functions def make_id(self, name): """Replace all characters not allowed for (X)HTML ids.""" - return name.replace('/', '_') + return name.replace('/', '_').replace(' ', '') def esc(self, name): """Replace all characters not allowed in text an attribute values.""" @@ -157,34 +190,20 @@ class EpubBuilder(StandaloneHTMLBuilder): name = name.replace('\'', ''') return name - def collapse_text(self, doctree, result): - """Remove all HTML markup and return only the text nodes.""" - for c in doctree.children: - if isinstance(c, nodes.Text): - try: - # docutils 0.4 and 0.5: Text is a UserString subclass - result.append(c.data) - except AttributeError: - # docutils 0.6: Text is a unicode subclass - result.append(c) - else: - result = self.collapse_text(c, result) - return result - def get_refnodes(self, doctree, result): """Collect section titles, their depth in the toc and the refuri.""" # XXX: is there a better way than checking the attribute - # toctree-l[1-6] on the parent node? + # toctree-l[1-8] on the parent node? if isinstance(doctree, nodes.reference): classes = doctree.parent.attributes['classes'] level = 1 - for l in range(5,0,-1): # or range(1,6)? + for l in range(8, 0, -1): # or range(1, 8)? if (_toctree_template % l) in classes: level = l result.append({ 'level': level, 'refuri': self.esc(doctree['refuri']), - 'text': self.esc(''.join(self.collapse_text(doctree, []))) + 'text': self.esc(doctree.astext()) }) else: for elem in doctree.children: @@ -195,16 +214,14 @@ class EpubBuilder(StandaloneHTMLBuilder): """Get the total table of contents, containg the master_doc and pre and post files not managed by sphinx. """ - doctree = self.env.get_and_resolve_doctree(self.config.master_doc, self) + doctree = self.env.get_and_resolve_doctree(self.config.master_doc, + self, prune_toctrees=False) self.refnodes = self.get_refnodes(doctree, []) self.refnodes.insert(0, { 'level': 1, 'refuri': self.esc(self.config.master_doc + '.html'), - 'text': self.esc(''.join(self.collapse_text( - self.env.titles[self.config.master_doc], [] - ))), + 'text': self.esc(self.env.titles[self.config.master_doc].astext()) }) - # XXX: is reversed ok? for file, text in reversed(self.config.epub_pre_files): self.refnodes.insert(0, { 'level': 1, @@ -290,11 +307,10 @@ class EpubBuilder(StandaloneHTMLBuilder): for fn in files: filename = path.join(root, fn)[olen:] if filename in self.ignored_files: - # self.warn("ignoring %s" % filename) continue ext = path.splitext(filename)[-1] if ext not in _media_types: - self.warn("unknown mimetype for %s, ignoring" % filename) + self.warn('unknown mimetype for %s, ignoring' % filename) continue projectfiles.append(_file_template % { 'href': self.esc(filename), @@ -338,7 +354,7 @@ class EpubBuilder(StandaloneHTMLBuilder): """Insert nested navpoints for given node. The node and subnav are already rendered to text. """ - nlist = node.split('\n') + nlist = node.rsplit('\n', 1) nlist.insert(-1, subnav) return '\n'.join(nlist) @@ -356,8 +372,10 @@ class EpubBuilder(StandaloneHTMLBuilder): file = node['refuri'].split('#')[0] if file in self.ignored_files: continue + if node['level'] > self.config.epub_tocdepth: + continue if node['level'] == level: - navlist.append(self.new_navpoint(node,level)) + navlist.append(self.new_navpoint(node, level)) elif node['level'] == level + 1: navstack.append(navlist) navlist = [] @@ -398,6 +416,7 @@ class EpubBuilder(StandaloneHTMLBuilder): navpoints = self.build_navpoints(self.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') try: f.write(_toc_template % self.toc_metadata(level, navpoints)) diff --git a/sphinx/config.py b/sphinx/config.py index a7795777..b81958df 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -117,6 +117,7 @@ class Config(object): epub_pre_files = ([], 'env'), epub_post_files = ([], 'env'), epub_exclude_files = ([], 'env'), + epub_tocdepth = (3, 'env'), # LaTeX options latex_documents = ([], None), diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index 4e5b72e7..4472b5d2 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -258,6 +258,9 @@ latex_documents = [ # A list of files that should not be packed into the epub file. #epub_exclude_files = [] + +# The depth of the table of contents in toc.ncx. +#epub_tocdepth = 3 ''' INTERSPHINX_CONFIG = ''' diff --git a/sphinx/themes/epub/static/epub.css b/sphinx/themes/epub/static/epub.css index f941b79a..c6320c8c 100644 --- a/sphinx/themes/epub/static/epub.css +++ b/sphinx/themes/epub/static/epub.css @@ -420,6 +420,19 @@ div.footer a { text-decoration: underline; } +/* -- link-target ----------------------------------------------------------- */ + +.link-target { + font-size: 80%; +} + +table .link-target { + /* Do not show links in tables, there is not enough space */ + display: none; +} + +/* -- font-face ------------------------------------------------------------- */ + @font-face { font-family: "LiberationNarrow"; font-style: normal; |
