mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
merge with trunk
This commit is contained in:
commit
f3a2854ba9
1
AUTHORS
1
AUTHORS
@ -15,6 +15,7 @@ Other contributors, listed alphabetically, are:
|
||||
* Thomas Lamb -- linkcheck builder
|
||||
* Dan MacKinlay -- metadata fixes
|
||||
* Will Maier -- directory HTML builder
|
||||
* Roland Meister -- epub builder
|
||||
* Christopher Perkins -- autosummary integration
|
||||
* Benjamin Peterson -- unittests
|
||||
* Stefan Seefeld -- toctree improvements
|
||||
|
12
CHANGES
12
CHANGES
@ -1,8 +1,14 @@
|
||||
Release 1.0 (in development)
|
||||
============================
|
||||
|
||||
.. XXX add short info about domains
|
||||
|
||||
* Support for domains has been added.
|
||||
|
||||
* Support for docutils 0.4 has been removed.
|
||||
|
||||
* Added Epub builder.
|
||||
|
||||
* #284: All docinfo metadata is now put into the document metadata, not
|
||||
just the author.
|
||||
|
||||
@ -54,6 +60,12 @@ Release 1.0 (in development)
|
||||
Release 0.6.4 (in development)
|
||||
==============================
|
||||
|
||||
* #303: ``html_context`` values given on the command line via ``-A``
|
||||
should not override other values given in conf.py.
|
||||
|
||||
* Fix a bug preventing incremental rebuilds for the ``dirhtml``
|
||||
builder.
|
||||
|
||||
* #299: Fix the mangling of quotes in some literal blocks.
|
||||
|
||||
* #292: Fix path to the search index for the ``dirhtml`` builder.
|
||||
|
@ -19,6 +19,7 @@ help:
|
||||
@echo " dirhtml to make HTML files called index.html in directories"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " epub to make an epub file"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " changes to make an overview over all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@ -65,6 +66,11 @@ qthelp:
|
||||
@echo "To view the help collection:"
|
||||
@echo "# assistant -collectionFile _build/qthelp/Sphinx.qhc"
|
||||
|
||||
epub:
|
||||
mkdir -p _build/epub _build/doctrees
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) _build/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in _build/epub."
|
||||
latex:
|
||||
mkdir -p _build/latex _build/doctrees
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
|
||||
|
3
doc/_templates/layout.html
vendored
3
doc/_templates/layout.html
vendored
@ -1,10 +1,13 @@
|
||||
{% extends "!layout.html" %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ super() }}
|
||||
{%- if not embedded %}
|
||||
<style type="text/css">
|
||||
table.right { float: right; margin-left: 20px; }
|
||||
table.right td { border: 1px solid #ccc; }
|
||||
</style>
|
||||
{%- endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block rootrellink %}
|
||||
|
@ -63,6 +63,16 @@ The builder's "name" must be given to the **-b** command-line option of
|
||||
|
||||
Its name is ``devhelp``.
|
||||
|
||||
.. module:: sphinx.builders.epub
|
||||
.. class:: EpubBuilder
|
||||
|
||||
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
|
||||
`<http://www.idpf.org/specs.htm>`_ or `<http://en.wikipedia.org/wiki/EPUB>`_.
|
||||
|
||||
Its name is ``epub``.
|
||||
|
||||
.. module:: sphinx.builders.latex
|
||||
.. class:: LaTeXBuilder
|
||||
|
||||
|
13
doc/conf.py
13
doc/conf.py
@ -64,6 +64,19 @@ html_use_opensearch = 'http://sphinx.pocoo.org'
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Sphinxdoc'
|
||||
|
||||
# Epub fields
|
||||
epub_theme = 'epub'
|
||||
epub_basename = 'sphinx'
|
||||
epub_author = 'Georg Brandl'
|
||||
epub_publisher = 'http://sphinx.pocoo.org/'
|
||||
epub_scheme = 'url'
|
||||
epub_identifier = epub_publisher
|
||||
epub_pre_files = [('index', 'Welcome')]
|
||||
epub_exclude_files = ['_static/opensearch.xml', '_static/doctools.js',
|
||||
'_static/jquery.js', '_static/searchtools.js',
|
||||
'_static/basic.css', 'search.html']
|
||||
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation',
|
||||
|
@ -550,6 +550,96 @@ that use Sphinx' HTMLWriter class.
|
||||
Output file base name for HTML help builder. Default is ``'pydoc'``.
|
||||
|
||||
|
||||
.. _epub-options:
|
||||
|
||||
Options for epub output
|
||||
-----------------------
|
||||
|
||||
These options influence the epub output. As this builder derives from the HTML
|
||||
builder, the HTML options also apply where appropriate. The actual values for
|
||||
some of the options is not really important, they just have to be entered into
|
||||
the `Dublin Core metadata <http://dublincore.org/>`_.
|
||||
|
||||
.. confval:: epub_basename
|
||||
|
||||
The basename for the epub file. It defaults to the :confval:`project` name.
|
||||
|
||||
.. confval:: epub_theme
|
||||
|
||||
The HTML theme for the epub output. Since the default themes are not
|
||||
optimized for small screen space, using the same theme for HTML and epub
|
||||
output is usually not wise. This defaults to ``'epub'``, a theme designed to
|
||||
save visual space.
|
||||
|
||||
.. confval:: epub_title
|
||||
|
||||
The title of the document. It defaults to the :confval:`html_title` option
|
||||
but can be set independently for epub creation.
|
||||
|
||||
.. confval:: epub_author
|
||||
|
||||
The author of the document. This is put in the Dublin Core metadata. The
|
||||
default value is ``'unknown'``.
|
||||
|
||||
.. confval:: epub_language
|
||||
|
||||
The language of the document. This is put in the Dublin Core metadata. The
|
||||
default is the :confval:`language` option or ``'en'`` if unset.
|
||||
|
||||
.. confval:: epub_publisher
|
||||
|
||||
The publisher of the document. This is put in the Dublin Core metadata. You
|
||||
may use any sensible string, e.g. the project homepage. The default value is
|
||||
``'unknown'``.
|
||||
|
||||
.. confval:: epub_copyright
|
||||
|
||||
The copyright of the document. It defaults to the :confval:`copyright`
|
||||
option but can be set independently for epub creation.
|
||||
|
||||
.. confval:: epub_identifier
|
||||
|
||||
An identifier for the document. This is put in the Dublin Core metadata.
|
||||
For published documents this is the ISBN number, but you can also use an
|
||||
alternative scheme, e.g. the project homepage. The default value is
|
||||
``'unknown'``.
|
||||
|
||||
.. confval:: epub_scheme
|
||||
|
||||
The publication scheme for the :confval:`epub_identifier`. This is put in
|
||||
the Dublin Core metadata. For published books the scheme is ``'ISBN'``. If
|
||||
you use the project homepage, ``'URL'`` seems reasonable. The default value
|
||||
is ``'unknown'``.
|
||||
|
||||
.. confval:: epub_uid
|
||||
|
||||
A unique identifier for the document. This is put in the Dublin Core
|
||||
metadata. You may use a random string. The default value is ``'unknown'``.
|
||||
|
||||
.. confval:: epub_pre_files
|
||||
|
||||
Additional files that should be inserted before the text generated by
|
||||
Sphinx. It is a list of tuples containing the file name and the title.
|
||||
Example::
|
||||
|
||||
epub_pre_files = [
|
||||
('index.html', 'Welcome'),
|
||||
]
|
||||
|
||||
The default value is ``[]``.
|
||||
|
||||
.. confval:: epub_post_files
|
||||
|
||||
Additional files that should be inserted after the text generated by Sphinx.
|
||||
It is a list of tuples containing the file name and the title. The default
|
||||
value is ``[]``.
|
||||
|
||||
.. confval:: epub_exclude_files
|
||||
|
||||
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 ``[]``.
|
||||
|
||||
|
||||
.. _latex-options:
|
||||
|
||||
Options for LaTeX output
|
||||
|
37
doc/faq.rst
37
doc/faq.rst
@ -66,3 +66,40 @@ github pages
|
||||
|
||||
.. _api role: http://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py
|
||||
.. _xhtml to reST: http://docutils.sourceforge.net/sandbox/xhtml2rest/xhtml2rest.py
|
||||
|
||||
|
||||
.. _epub-faq:
|
||||
|
||||
Epub info
|
||||
---------
|
||||
|
||||
The epub builder is currently in an experimental stage. It has only been tested
|
||||
with the Sphinx documentation itself. If you want to create epubs, here are
|
||||
some notes:
|
||||
|
||||
* Split the text into several files. The longer the individual HTML files are,
|
||||
the longer it takes the ebook reader to render them. In extreme cases, the
|
||||
rendering can take up to one minute.
|
||||
|
||||
* Try to minimize the markup. This also pays in rendering time.
|
||||
|
||||
* For some readers you can use embedded or external fonts using the CSS
|
||||
``@font-face`` directive. This is *extremely* useful for code listings which
|
||||
are often cut at the right margin. The default Courier font (or variant) is
|
||||
quite wide and you can only display up to 60 characters on a line. If you
|
||||
replace it with a narrower font, you can get more characters on a line. You
|
||||
may even use `FontForge <http://fontforge.sourceforge.net/>`_ and create
|
||||
narrow variants of some free font. In my case I get up to 70 characters on a
|
||||
line.
|
||||
|
||||
You may have to experiment a little until you get reasonable results.
|
||||
|
||||
* Test the created epubs. You can use several alternatives. The ones I am aware
|
||||
of are Epubcheck_, Calibre_, FBreader_ (although it does not render the CSS),
|
||||
and Bookworm_. For bookworm you can download the source from
|
||||
http://code.google.com/p/threepress/ and run your own local server.
|
||||
|
||||
.. _Epubcheck: http://code.google.com/p/epubcheck/
|
||||
.. _Calibre: http://calibre-ebook.com/
|
||||
.. _FBreader: http://www.fbreader.org/
|
||||
.. _Bookworm: http://bookworm.oreilly.com/
|
||||
|
@ -160,6 +160,10 @@ These themes are:
|
||||
* **traditional** -- A theme resembling the old Python documentation. There are
|
||||
currently no options beyond *nosidebar*.
|
||||
|
||||
* **epub** -- A theme for the epub builder. There are currently no options.
|
||||
This theme tries to save visual space which is a sparse resource on ebook
|
||||
readers.
|
||||
|
||||
|
||||
Creating themes
|
||||
---------------
|
||||
|
@ -323,6 +323,7 @@ BUILTIN_BUILDERS = {
|
||||
'htmlhelp': ('htmlhelp', 'HTMLHelpBuilder'),
|
||||
'devhelp': ('devhelp', 'DevhelpBuilder'),
|
||||
'qthelp': ('qthelp', 'QtHelpBuilder'),
|
||||
'epub': ('epub', 'EpubBuilder'),
|
||||
'latex': ('latex', 'LaTeXBuilder'),
|
||||
'text': ('text', 'TextBuilder'),
|
||||
'changes': ('changes', 'ChangesBuilder'),
|
||||
|
421
sphinx/builders/epub.py
Normal file
421
sphinx/builders/epub.py
Normal file
@ -0,0 +1,421 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
sphinx.builders.epub
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Build epub files.
|
||||
Originally derived from qthelp.py.
|
||||
|
||||
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
import os
|
||||
import codecs
|
||||
from os import path
|
||||
import zipfile
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
|
||||
|
||||
# (Fragment) templates from which the metainfo files content.opf, toc.ncx,
|
||||
# mimetype, and META-INF/container.xml are created.
|
||||
|
||||
_mimetype_template = 'application/epub+zip' # no EOL!
|
||||
|
||||
_container_template = u'''\
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<container version="1.0"
|
||||
xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
|
||||
<rootfiles>
|
||||
<rootfile full-path="content.opf"
|
||||
media-type="application/oebps-package+xml"/>
|
||||
</rootfiles>
|
||||
</container>
|
||||
'''
|
||||
|
||||
_toc_template = u'''\
|
||||
<?xml version="1.0"?>
|
||||
<ncx version="2005-1" xmlns="http://www.daisy.org/z3986/2005/ncx/">
|
||||
<head>
|
||||
<meta name="dtb:uid" content="%(uid)s"/>
|
||||
<meta name="dtb:depth" content="%(level)d"/>
|
||||
<meta name="dtb:totalPageCount" content="0"/>
|
||||
<meta name="dtb:maxPageNumber" content="0"/>
|
||||
</head>
|
||||
<docTitle>
|
||||
<text>%(title)s</text>
|
||||
</docTitle>
|
||||
<navMap>
|
||||
%(navpoints)s
|
||||
</navMap>
|
||||
</ncx>
|
||||
'''
|
||||
|
||||
_navpoint_template = u'''\
|
||||
%(indent)s <navPoint id="%(navpoint)s" playOrder="%(playorder)d">
|
||||
%(indent)s <navLabel>
|
||||
%(indent)s <text>%(text)s</text>
|
||||
%(indent)s </navLabel>
|
||||
%(indent)s <content src="%(refuri)s" />
|
||||
%(indent)s </navPoint>'''
|
||||
|
||||
_navpoint_indent = ' '
|
||||
_navPoint_template = 'navPoint%d'
|
||||
|
||||
_content_template = u'''\
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<package xmlns="http://www.idpf.org/2007/opf" version="2.0"
|
||||
unique-identifier="%(uid)s">
|
||||
<metadata xmlns:opf="http://www.idpf.org/2007/opf"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<dc:language>%(lang)s</dc:language>
|
||||
<dc:title>%(title)s</dc:title>
|
||||
<dc:creator opf:role="aut">%(author)s</dc:creator>
|
||||
<dc:publisher>%(publisher)s</dc:publisher>
|
||||
<dc:rights>%(copyright)s</dc:rights>
|
||||
<dc:identifier id="%(uid)s" opf:scheme="%(scheme)s">%(id)s</dc:identifier>
|
||||
</metadata>
|
||||
<manifest>
|
||||
<item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" />
|
||||
%(files)s
|
||||
</manifest>
|
||||
<spine toc="ncx">
|
||||
%(spine)s
|
||||
</spine>
|
||||
</package>
|
||||
'''
|
||||
|
||||
_file_template = u'''\
|
||||
<item id="%(id)s"
|
||||
href="%(href)s"
|
||||
media-type="%(media_type)s" />'''
|
||||
|
||||
_spine_template = u'''\
|
||||
<itemref idref="%(idref)s" />'''
|
||||
|
||||
_toctree_template = u'toctree-l%d'
|
||||
|
||||
_media_types = {
|
||||
'.html': 'application/xhtml+xml',
|
||||
'.css': 'text/css',
|
||||
'.png': 'image/png',
|
||||
'.gif': 'image/gif',
|
||||
'.svg': 'image/svg+xml',
|
||||
'.jpg': 'image/jpeg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
'.otf': 'application/x-font-otf',
|
||||
'.ttf': 'application/x-font-ttf',
|
||||
}
|
||||
|
||||
|
||||
# The epub publisher
|
||||
|
||||
class EpubBuilder(StandaloneHTMLBuilder):
|
||||
"""Builder that outputs epub files.
|
||||
|
||||
It creates the metainfo files container.opf, toc.ncx, mimetype, and
|
||||
META-INF/container.xml. Afterwards, all necessary files are zipped to an
|
||||
epub file.
|
||||
"""
|
||||
name = 'epub'
|
||||
|
||||
# don't copy the reST source
|
||||
copysource = False
|
||||
supported_image_types = ['image/svg+xml', 'image/png', 'image/gif',
|
||||
'image/jpeg']
|
||||
|
||||
# don't add links
|
||||
add_permalinks = False
|
||||
# don't add sidebar etc.
|
||||
embedded = True
|
||||
|
||||
def init(self):
|
||||
StandaloneHTMLBuilder.init(self)
|
||||
# the output files for epub must be .html only
|
||||
self.out_suffix = '.html'
|
||||
self.playorder = 0
|
||||
|
||||
def get_theme_config(self):
|
||||
return self.config.epub_theme, {}
|
||||
|
||||
# generic support functions
|
||||
def make_id(self, name):
|
||||
"""Replace all characters not allowed for (X)HTML ids."""
|
||||
return name.replace('/', '_')
|
||||
|
||||
def esc(self, name):
|
||||
"""Replace all characters not allowed in text an attribute values."""
|
||||
# Like cgi.escape, but also replace apostrophe
|
||||
name = name.replace('&', '&')
|
||||
name = name.replace('<', '<')
|
||||
name = name.replace('>', '>')
|
||||
name = name.replace('"', '"')
|
||||
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?
|
||||
if isinstance(doctree, nodes.reference):
|
||||
classes = doctree.parent.attributes['classes']
|
||||
level = 1
|
||||
for l in range(5,0,-1): # or range(1,6)?
|
||||
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, [])))
|
||||
})
|
||||
else:
|
||||
for elem in doctree.children:
|
||||
result = self.get_refnodes(elem, result)
|
||||
return result
|
||||
|
||||
def get_toc(self):
|
||||
"""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)
|
||||
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], []
|
||||
))),
|
||||
})
|
||||
# XXX: is reversed ok?
|
||||
for file, text in reversed(self.config.epub_pre_files):
|
||||
self.refnodes.insert(0, {
|
||||
'level': 1,
|
||||
'refuri': self.esc(file + '.html'),
|
||||
'text': self.esc(text)
|
||||
})
|
||||
for file, text in self.config.epub_post_files:
|
||||
self.refnodes.append({
|
||||
'level': 1,
|
||||
'refuri': self.esc(file + '.html'),
|
||||
'text': self.esc(text)
|
||||
})
|
||||
|
||||
|
||||
# Finish by building the epub file
|
||||
def handle_finish(self):
|
||||
"""Create the metainfo files and finally the epub."""
|
||||
self.get_toc()
|
||||
self.build_mimetype(self.outdir, 'mimetype')
|
||||
self.build_container(self.outdir, 'META-INF/container.xml')
|
||||
self.build_content(self.outdir, 'content.opf')
|
||||
self.build_toc(self.outdir, 'toc.ncx')
|
||||
self.build_epub(self.outdir, self.config.epub_basename + '.epub')
|
||||
|
||||
def build_mimetype(self, outdir, outname):
|
||||
"""Write the metainfo file mimetype."""
|
||||
self.info('writing %s file...' % outname)
|
||||
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
|
||||
try:
|
||||
f.write(_mimetype_template)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def build_container(self, outdir, outname):
|
||||
"""Write the metainfo file META-INF/cointainer.xml."""
|
||||
self.info('writing %s file...' % outname)
|
||||
fn = path.join(outdir, outname)
|
||||
try:
|
||||
os.mkdir(path.dirname(fn))
|
||||
except OSError, err:
|
||||
if err.errno != os.errno.EEXIST:
|
||||
raise
|
||||
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
|
||||
try:
|
||||
f.write(_container_template)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def content_metadata(self, files, spine):
|
||||
"""Create a dictionary with all metadata for the content.opf
|
||||
file properly escaped.
|
||||
"""
|
||||
metadata = {}
|
||||
metadata['title'] = self.esc(self.config.epub_title)
|
||||
metadata['author'] = self.esc(self.config.epub_author)
|
||||
metadata['uid'] = self.esc(self.config.epub_uid)
|
||||
metadata['lang'] = self.esc(self.config.epub_language)
|
||||
metadata['publisher'] = self.esc(self.config.epub_publisher)
|
||||
metadata['copyright'] = self.esc(self.config.epub_copyright)
|
||||
metadata['scheme'] = self.esc(self.config.epub_scheme)
|
||||
metadata['id'] = self.esc(self.config.epub_identifier)
|
||||
metadata['files'] = files
|
||||
metadata['spine'] = spine
|
||||
return metadata
|
||||
|
||||
def build_content(self, outdir, outname):
|
||||
"""Write the metainfo file content.opf It contains bibliographic data,
|
||||
a file list and the spine (the reading order).
|
||||
"""
|
||||
self.info('writing %s file...' % outname)
|
||||
|
||||
# files
|
||||
if not outdir.endswith(os.sep):
|
||||
outdir += os.sep
|
||||
olen = len(outdir)
|
||||
projectfiles = []
|
||||
self.files = []
|
||||
self.ignored_files = ['.buildinfo',
|
||||
'mimetype', 'content.opf', 'toc.ncx', 'META-INF/container.xml',
|
||||
self.config.epub_basename + '.epub'] + \
|
||||
self.config.epub_exclude_files
|
||||
for root, dirs, files in os.walk(outdir):
|
||||
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)
|
||||
continue
|
||||
projectfiles.append(_file_template % {
|
||||
'href': self.esc(filename),
|
||||
'id': self.esc(self.make_id(filename)),
|
||||
'media_type': self.esc(_media_types[ext])
|
||||
})
|
||||
self.files.append(filename)
|
||||
projectfiles = '\n'.join(projectfiles)
|
||||
|
||||
# spine
|
||||
spine = []
|
||||
for item in self.refnodes:
|
||||
if '#' in item['refuri']:
|
||||
continue
|
||||
if item['refuri'] in self.ignored_files:
|
||||
continue
|
||||
spine.append(_spine_template % {
|
||||
'idref': self.esc(self.make_id(item['refuri']))
|
||||
})
|
||||
spine = '\n'.join(spine)
|
||||
|
||||
# write the project file
|
||||
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
|
||||
try:
|
||||
f.write(_content_template % \
|
||||
self.content_metadata(projectfiles, spine))
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def new_navpoint(self, node, level, incr=True):
|
||||
"""Create a new entry in the toc from the node at given level."""
|
||||
# XXX Modifies the node
|
||||
if incr:
|
||||
self.playorder += 1
|
||||
node['indent'] = _navpoint_indent * level
|
||||
node['navpoint'] = self.esc(_navPoint_template % self.playorder)
|
||||
node['playorder'] = self.playorder
|
||||
return _navpoint_template % node
|
||||
|
||||
def insert_subnav(self, node, subnav):
|
||||
"""Insert nested navpoints for given node.
|
||||
The node and subnav are already rendered to text.
|
||||
"""
|
||||
nlist = node.split('\n')
|
||||
nlist.insert(-1, subnav)
|
||||
return '\n'.join(nlist)
|
||||
|
||||
def build_navpoints(self, nodes):
|
||||
"""Create the toc navigation structure.
|
||||
|
||||
Subelements of a node are nested inside the navpoint.
|
||||
For nested nodes the parent node is reinserted in the subnav.
|
||||
"""
|
||||
navstack = []
|
||||
navlist = []
|
||||
level = 1
|
||||
lastnode = None
|
||||
for node in nodes:
|
||||
file = node['refuri'].split('#')[0]
|
||||
if file in self.ignored_files:
|
||||
continue
|
||||
if node['level'] == level:
|
||||
navlist.append(self.new_navpoint(node,level))
|
||||
elif node['level'] == level + 1:
|
||||
navstack.append(navlist)
|
||||
navlist = []
|
||||
level += 1
|
||||
if lastnode:
|
||||
# Insert starting point in subtoc with same playOrder
|
||||
navlist.append(self.new_navpoint(lastnode, level, False))
|
||||
navlist.append(self.new_navpoint(node, level))
|
||||
else:
|
||||
while node['level'] < level:
|
||||
subnav = '\n'.join(navlist)
|
||||
navlist = navstack.pop()
|
||||
navlist[-1] = self.insert_subnav(navlist[-1], subnav)
|
||||
level -= 1
|
||||
navlist.append(self.new_navpoint(node, level))
|
||||
lastnode = node
|
||||
while level != 1:
|
||||
subnav = '\n'.join(navlist)
|
||||
navlist = navstack.pop()
|
||||
navlist[-1] = self.insert_subnav(navlist[-1], subnav)
|
||||
level -= 1
|
||||
return '\n'.join(navlist)
|
||||
|
||||
def toc_metadata(self, level, navpoints):
|
||||
"""Create a dictionary with all metadata for the toc.ncx
|
||||
file properly escaped.
|
||||
"""
|
||||
metadata = {}
|
||||
metadata['uid'] = self.config.epub_uid
|
||||
metadata['title'] = self.config.epub_title
|
||||
metadata['level'] = level
|
||||
metadata['navpoints'] = navpoints
|
||||
return metadata
|
||||
|
||||
def build_toc(self, outdir, outname):
|
||||
"""Write the metainfo file toc.ncx."""
|
||||
self.info('writing %s file...' % outname)
|
||||
|
||||
navpoints = self.build_navpoints(self.refnodes)
|
||||
level = max(item['level'] for item in self.refnodes)
|
||||
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
|
||||
try:
|
||||
f.write(_toc_template % self.toc_metadata(level, navpoints))
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def build_epub(self, outdir, outname):
|
||||
"""Write the epub file.
|
||||
|
||||
It is a zip file with the mimetype file stored uncompressed
|
||||
as the first entry.
|
||||
"""
|
||||
self.info('writing %s file...' % outname)
|
||||
projectfiles = ['META-INF/container.xml', 'content.opf', 'toc.ncx'] \
|
||||
+ self.files
|
||||
epub = zipfile.ZipFile(path.join(outdir, outname), 'w', \
|
||||
zipfile.ZIP_DEFLATED)
|
||||
epub.write(path.join(outdir, 'mimetype'), 'mimetype', \
|
||||
zipfile.ZIP_STORED)
|
||||
for file in projectfiles:
|
||||
epub.write(path.join(outdir, file), file, zipfile.ZIP_DEFLATED)
|
||||
epub.close()
|
@ -103,9 +103,14 @@ class StandaloneHTMLBuilder(Builder):
|
||||
if path.isfile(jsfile):
|
||||
self.script_files.append('_static/translations.js')
|
||||
|
||||
def get_theme_config(self):
|
||||
return self.config.html_theme, self.config.html_theme_options
|
||||
|
||||
def init_templates(self):
|
||||
Theme.init_themes(self)
|
||||
self.theme = Theme(self.config.html_theme)
|
||||
themename, themeoptions = self.get_theme_config()
|
||||
self.theme = Theme(themename)
|
||||
self.theme_options = themeoptions.copy()
|
||||
self.create_template_bridge()
|
||||
self.templates.init(self, self.theme)
|
||||
|
||||
@ -169,8 +174,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
if docname not in self.env.all_docs:
|
||||
yield docname
|
||||
continue
|
||||
targetname = self.env.doc2path(docname, self.outdir,
|
||||
self.out_suffix)
|
||||
targetname = self.get_outfilename(docname)
|
||||
try:
|
||||
targetmtime = path.getmtime(targetname)
|
||||
except Exception:
|
||||
@ -283,8 +287,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
if self.theme:
|
||||
self.globalcontext.update(
|
||||
('theme_' + key, val) for (key, val) in
|
||||
self.theme.get_options(
|
||||
self.config.html_theme_options).iteritems())
|
||||
self.theme.get_options(self.theme_options).iteritems())
|
||||
self.globalcontext.update(self.config.html_context)
|
||||
|
||||
def get_doc_context(self, docname, body, metatags):
|
||||
|
@ -96,7 +96,6 @@ def main(argv):
|
||||
error = sys.stderr
|
||||
warnfile = None
|
||||
confoverrides = {}
|
||||
htmlcontext = {}
|
||||
tags = []
|
||||
doctreedir = path.join(outdir, '.doctrees')
|
||||
for opt, val in opts:
|
||||
@ -142,7 +141,7 @@ def main(argv):
|
||||
val = int(val)
|
||||
except ValueError:
|
||||
pass
|
||||
htmlcontext[key] = val
|
||||
confoverrides['html_context.%s' % key] = val
|
||||
elif opt == '-N':
|
||||
nocolor()
|
||||
elif opt == '-E':
|
||||
@ -158,7 +157,6 @@ def main(argv):
|
||||
warnfile = val
|
||||
elif opt == '-P':
|
||||
use_pdb = True
|
||||
confoverrides['html_context'] = htmlcontext
|
||||
|
||||
if warning and warnfile:
|
||||
warnfp = open(warnfile, 'w')
|
||||
|
@ -98,6 +98,21 @@ class Config(object):
|
||||
# Devhelp only options
|
||||
devhelp_basename = (lambda self: make_filename(self.project), None),
|
||||
|
||||
# Epub options
|
||||
epub_basename = (lambda self: make_filename(self.project), None),
|
||||
epub_theme = ('epub', 'html'),
|
||||
epub_title = (lambda self: self.html_title, 'html'),
|
||||
epub_author = ('unknown', 'html'),
|
||||
epub_language = (lambda self: self.language or 'en', 'html'),
|
||||
epub_publisher = ('unknown', 'html'),
|
||||
epub_copyright = (lambda self: self.copyright, 'html'),
|
||||
epub_identifier = ('unknown', 'html'),
|
||||
epub_scheme = ('unknown', 'html'),
|
||||
epub_uid = ('unknown', 'env'),
|
||||
epub_pre_files = ([], 'env'),
|
||||
epub_post_files = ([], 'env'),
|
||||
epub_exclude_files = ([], 'env'),
|
||||
|
||||
# LaTeX options
|
||||
latex_documents = ([], None),
|
||||
latex_logo = (None, None),
|
||||
|
@ -148,7 +148,7 @@ class Index(Directive):
|
||||
option_spec = {}
|
||||
|
||||
indextypes = [
|
||||
'single', 'pair', 'triple',
|
||||
'single', 'pair', 'double', 'triple',
|
||||
]
|
||||
|
||||
def run(self):
|
||||
@ -171,6 +171,8 @@ class Index(Directive):
|
||||
for type in self.indextypes:
|
||||
if entry.startswith(type+':'):
|
||||
value = entry[len(type)+1:].strip()
|
||||
if type == 'double':
|
||||
type = 'pair'
|
||||
ne.append((type, value, targetid, value))
|
||||
break
|
||||
# shorthand notation for single entries
|
||||
|
@ -223,6 +223,40 @@ latex_documents = [
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_use_modindex = True
|
||||
|
||||
|
||||
# -- Options for Epub output ---------------------------------------------------
|
||||
|
||||
# Bibliographic Dublin Core info.
|
||||
#epub_title = ''
|
||||
#epub_author = ''
|
||||
#epub_publisher = ''
|
||||
#epub_copyright = ''
|
||||
|
||||
# The language of the text. It defaults to the language option
|
||||
# or en if the language is not set.
|
||||
#epub_language = ''
|
||||
|
||||
# The scheme of the identifier. Typical schemes are ISBN or URL.
|
||||
#epub_scheme = ''
|
||||
|
||||
# The unique identifier of the text. This can be a ISBN number
|
||||
# or the project homepage.
|
||||
#epub_identifier = ''
|
||||
|
||||
# A unique identification for the text.
|
||||
#epub_uid = ''
|
||||
|
||||
# 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 = []
|
||||
|
||||
# HTML files shat should be inserted after the pages created by sphinx.
|
||||
# The format is a list of tuples containing the path and title.
|
||||
#epub_post_files = []
|
||||
|
||||
# A list of files that should not be packed into the epub file.
|
||||
#epub_exclude_files = []
|
||||
'''
|
||||
|
||||
INTERSPHINX_CONFIG = '''
|
||||
@ -270,8 +304,8 @@ PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) \
|
||||
$(SPHINXOPTS) %(rsrcdir)s
|
||||
|
||||
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes \
|
||||
linkcheck doctest
|
||||
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp epub \
|
||||
latex changes linkcheck doctest
|
||||
|
||||
help:
|
||||
\t@echo "Please use \\`make <target>' where <target> is one of"
|
||||
@ -282,6 +316,7 @@ help:
|
||||
\t@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
\t@echo " qthelp to make HTML files and a qthelp project"
|
||||
\t@echo " devhelp to make HTML files and a Devhelp project"
|
||||
\t@echo " epub to make an epub"
|
||||
\t@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
\t@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
\t@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@ -337,6 +372,11 @@ devhelp:
|
||||
$$HOME/.local/share/devhelp/%(project_fn)s"
|
||||
\t@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
\t@echo
|
||||
\t@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
\t@echo
|
||||
@ -391,6 +431,7 @@ if "%%1" == "help" (
|
||||
\techo. htmlhelp to make HTML files and a HTML help project
|
||||
\techo. qthelp to make HTML files and a qthelp project
|
||||
\techo. devhelp to make HTML files and a Devhelp project
|
||||
\techo. epub to make an epub
|
||||
\techo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
\techo. changes to make an overview over all changed/added/deprecated items
|
||||
\techo. linkcheck to check all external links for integrity
|
||||
@ -458,6 +499,13 @@ if "%%1" == "devhelp" (
|
||||
\tgoto end
|
||||
)
|
||||
|
||||
if "%%1" == "epub" (
|
||||
\t%%SPHINXBUILD%% -b epub %%ALLSPHINXOPTS%% %%BUILDDIR%%/epub
|
||||
\techo.
|
||||
\techo.Build finished. The epub file is in %%BUILDDIR%%/epub.
|
||||
\tgoto end
|
||||
)
|
||||
|
||||
if "%%1" == "latex" (
|
||||
\t%%SPHINXBUILD%% -b latex %%ALLSPHINXOPTS%% %%BUILDDIR%%/latex
|
||||
\techo.
|
||||
|
7
sphinx/themes/epub/layout.html
Normal file
7
sphinx/themes/epub/layout.html
Normal file
@ -0,0 +1,7 @@
|
||||
{% extends "basic/layout.html" %}
|
||||
|
||||
{# add only basic navigation links #}
|
||||
{% block sidebar1 %}{% endblock %}
|
||||
{% block sidebar2 %}{% endblock %}
|
||||
{% block relbar2 %}{% endblock %}
|
||||
{% block linktags %}{% endblock %}
|
445
sphinx/themes/epub/static/epub.css
Normal file
445
sphinx/themes/epub/static/epub.css
Normal file
@ -0,0 +1,445 @@
|
||||
/**
|
||||
* Sphinx stylesheet -- epub theme
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
|
||||
/* -- main layout ----------------------------------------------------------- */
|
||||
|
||||
div.clearer {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
color: #3333ff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* -- relbar ---------------------------------------------------------------- */
|
||||
|
||||
div.related {
|
||||
width: 100%;
|
||||
font-family: sans-serif;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.related h3 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.related ul {
|
||||
margin: 0;
|
||||
padding: 0 0 0 10px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.related li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.related li.right {
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* -- sidebar --------------------------------------------------------------- */
|
||||
|
||||
div.sphinxsidebarwrapper {
|
||||
padding: 10px 5px 0 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
float: left;
|
||||
width: 230px;
|
||||
margin-left: -100%;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul,
|
||||
div.sphinxsidebar ul.want-points {
|
||||
margin-left: 20px;
|
||||
list-style: square;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar form {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input {
|
||||
border: 1px solid #98dbcc;
|
||||
font-family: sans-serif;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* -- search page ----------------------------------------------------------- */
|
||||
|
||||
ul.search {
|
||||
margin: 10px 0 0 20px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.search li {
|
||||
padding: 5px 0 5px 20px;
|
||||
background-image: url(file.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 7px;
|
||||
}
|
||||
|
||||
ul.search li a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.search li div.context {
|
||||
color: #888;
|
||||
margin: 2px 0 0 30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul.keywordmatches li.goodmatch a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* -- index page ------------------------------------------------------------ */
|
||||
|
||||
table.contentstable {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
table.contentstable p.biglink {
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
a.biglink {
|
||||
font-size: 130%;
|
||||
}
|
||||
|
||||
span.linkdescr {
|
||||
font-style: italic;
|
||||
padding-top: 5px;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
/* -- general index --------------------------------------------------------- */
|
||||
|
||||
table.indextable td {
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.indextable dl, table.indextable dd {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
table.indextable tr.pcap {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
table.indextable tr.cap {
|
||||
margin-top: 10px;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
img.toggler {
|
||||
margin-right: 3px;
|
||||
margin-top: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* -- general body styles --------------------------------------------------- */
|
||||
|
||||
a.headerlink {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
div.body p.caption {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
div.body td {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.field-list ul {
|
||||
padding-left: 100%;
|
||||
}
|
||||
|
||||
.first {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
p.rubric {
|
||||
margin-top: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* -- sidebars -------------------------------------------------------------- */
|
||||
|
||||
div.sidebar {
|
||||
margin: 0 0 0.5em 1em;
|
||||
border: 1px solid #ddb;
|
||||
padding: 7px 7px 0 7px;
|
||||
background-color: #ffe;
|
||||
width: 40%;
|
||||
float: right;
|
||||
}
|
||||
|
||||
p.sidebar-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* -- topics ---------------------------------------------------------------- */
|
||||
|
||||
div.topic {
|
||||
border: 1px solid #ccc;
|
||||
padding: 7px 7px 0 7px;
|
||||
margin: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
p.topic-title {
|
||||
font-size: 110%;
|
||||
font-weight: bold;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* -- admonitions ----------------------------------------------------------- */
|
||||
|
||||
div.admonition {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
div.admonition dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.admonition dl {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
margin: 0px 10px 5px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.body p.centered {
|
||||
text-align: center;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
/* -- tables ---------------------------------------------------------------- */
|
||||
|
||||
table.docutils {
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table.docutils td, table.docutils th {
|
||||
padding: 1px 8px 1px 5px;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
|
||||
table.field-list td, table.field-list th {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
table.footnote td, table.footnote th {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
/* -- other body styles ----------------------------------------------------- */
|
||||
|
||||
dl {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
dd p {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
dd ul, dd table {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
dt:target, .highlight {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
dl.glossary dt {
|
||||
font-weight: bold;
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
.field-list ul {
|
||||
margin: 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.field-list p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.refcount {
|
||||
color: #060;
|
||||
}
|
||||
|
||||
.optional {
|
||||
font-size: 130%;
|
||||
}
|
||||
|
||||
.versionmodified {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.system-message {
|
||||
background-color: #fda;
|
||||
padding: 5px;
|
||||
border: 3px solid red;
|
||||
}
|
||||
|
||||
.footnote:target {
|
||||
background-color: #dddddd;
|
||||
}
|
||||
|
||||
/* -- code displays --------------------------------------------------------- */
|
||||
|
||||
pre {
|
||||
font-family: "LiberationNarrow", monospace;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
td.linenos pre {
|
||||
padding: 5px 0px;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
table.highlighttable {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
table.highlighttable td {
|
||||
padding: 0 0.5em 0 0.5em;
|
||||
}
|
||||
|
||||
tt {
|
||||
font-family: "LiberationNarrow", monospace;
|
||||
}
|
||||
|
||||
tt.descname {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
tt.descclassname {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
tt.xref, a tt {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/* -- math display ---------------------------------------------------------- */
|
||||
|
||||
img.math {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.body div.math p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
span.eqno {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* -- special divs --------------------------------------------------------- */
|
||||
|
||||
div.quotebar {
|
||||
background-color: #e3eff1;
|
||||
max-width: 250px;
|
||||
float: right;
|
||||
font-family: sans-serif;
|
||||
padding: 7px 7px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
div.footer {
|
||||
background-color: #e3eff1;
|
||||
padding: 3px 8px 3px 0;
|
||||
clear: both;
|
||||
font-family: sans-serif;
|
||||
font-size: 80%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.footer a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "LiberationNarrow";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: url("res:///Data/fonts/LiberationNarrow-Regular.otf")
|
||||
format("opentype");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "LiberationNarrow";
|
||||
font-style: oblique, italic;
|
||||
font-weight: normal;
|
||||
src: url("res:///Data/fonts/LiberationNarrow-Italic.otf")
|
||||
format("opentype");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "LiberationNarrow";
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
src: url("res:///Data/fonts/LiberationNarrow-Bold.otf")
|
||||
format("opentype");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "LiberationNarrow";
|
||||
font-style: oblique, italic;
|
||||
font-weight: bold;
|
||||
src: url("res:///Data/fonts/LiberationNarrow-BoldItalic.otf")
|
||||
format("opentype");
|
||||
}
|
||||
|
4
sphinx/themes/epub/theme.conf
Normal file
4
sphinx/themes/epub/theme.conf
Normal file
@ -0,0 +1,4 @@
|
||||
[theme]
|
||||
inherit = basic
|
||||
stylesheet = epub.css
|
||||
pygments_style = none
|
@ -1,7 +1,10 @@
|
||||
{% extends "!layout.html" %}
|
||||
|
||||
{% block extrahead %}
|
||||
{# html_context variable from conf.py #}
|
||||
<meta name="hc" content="{{ hckey }}" />
|
||||
{# html_context variable from confoverrides (as if given on cmdline) #}
|
||||
<meta name="hc_co" content="{{ hckey_co }}" />
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -36,7 +36,7 @@ html_theme_options = {'testopt': 'testoverride'}
|
||||
html_style = 'default.css'
|
||||
html_static_path = ['_static']
|
||||
html_last_updated_fmt = '%b %d, %Y'
|
||||
html_context = {'hckey': 'hcval'}
|
||||
html_context = {'hckey': 'hcval', 'hckey_co': 'wrong_hcval_co'}
|
||||
|
||||
htmlhelp_basename = 'SphinxTestsdoc'
|
||||
|
||||
|
@ -227,6 +227,7 @@ Index markup
|
||||
.. index::
|
||||
single: entry
|
||||
pair: entry; pair
|
||||
double: entry; double
|
||||
triple: index; entry; triple
|
||||
keyword: with
|
||||
|
||||
|
@ -124,6 +124,10 @@ def test_htmlhelp(app):
|
||||
def test_qthelp(app):
|
||||
app.builder.build_all()
|
||||
|
||||
@with_app(buildername='epub')
|
||||
def test_epub(app):
|
||||
app.builder.build_all()
|
||||
|
||||
@with_app(buildername='changes', cleanenv=True)
|
||||
def test_changes(app):
|
||||
app.builder.build_all()
|
||||
|
@ -152,6 +152,7 @@ HTML_XPATH = {
|
||||
},
|
||||
'contents.html': {
|
||||
".//meta[@name='hc'][@content='hcval']": '',
|
||||
".//meta[@name='hc_co'][@content='hcval_co']": '',
|
||||
".//meta[@name='testopt'][@content='testoverride']": '',
|
||||
#".//td[@class='label']": r'\[Ref1\]', # docutils 0.5 only
|
||||
".//td[@class='label']": '',
|
||||
@ -228,6 +229,7 @@ def check_xpath(etree, fname, path, check):
|
||||
[node.text for node in nodes]))
|
||||
|
||||
@gen_with_app(buildername='html', warning=html_warnfile, cleanenv=True,
|
||||
confoverrides={'html_context.hckey_co': 'hcval_co'},
|
||||
tags=['testtag'])
|
||||
def test_html(app):
|
||||
app.builder.build_all()
|
||||
|
@ -25,7 +25,7 @@ def test_theme_api(app):
|
||||
# test Theme class API
|
||||
assert set(Theme.themes.keys()) == \
|
||||
set(['basic', 'default', 'scrolls', 'agogo', 'sphinxdoc',
|
||||
'traditional', 'testtheme', 'ziptheme'])
|
||||
'traditional', 'testtheme', 'ziptheme', 'epub'])
|
||||
assert Theme.themes['testtheme'][1] is None
|
||||
assert isinstance(Theme.themes['ziptheme'][1], zipfile.ZipFile)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user