Add feature: theme package collection by using setuptools plugin mechanism.

This commit is contained in:
Takayuki Shimizukawa 2013-09-16 23:57:58 +09:00
parent f784d763d2
commit 93e7623cd8
3 changed files with 74 additions and 3 deletions

View File

@ -16,6 +16,7 @@ Features added
* PR#136: Autodoc directives now support an ``imported-members`` option to
include members imported from different modules.
* New locales: Macedonian, Sinhala, Indonesian.
* Theme package collection by using setuptools plugin mechanism.
Incompatible changes
--------------------

View File

@ -34,7 +34,7 @@ That would give you the default theme, but with a sidebar on the right side and
a black background for the relation bar (the bar with the navigation links at
the page's top and bottom).
If the theme does not come with Sphinx, it can be in two forms: either a
If the theme does not come with Sphinx, it can be in two static forms: either a
directory (containing :file:`theme.conf` and other needed files), or a zip file
with the same contents. Either of them must be put where Sphinx can find it;
for this there is the config value :confval:`html_theme_path`. It gives a list
@ -46,6 +46,33 @@ file :file:`blue.zip`, you can put it right in the directory containing
html_theme = "blue"
html_theme_path = ["."]
The third form provides your theme path dynamically to Sphinx if ``setuptools``
installed. You can provide ``sphinx_themes`` entry_points section in your setup.py
and write get_path function in this case that return path of themes::
// in your 'setup.py'
setup(
...
entry_points = {
'sphinx_themes': [
'path = your_package:get_path',
]
},
...
)
// in 'your_package.py'
from os import path
package_dir = path.abspath(path.dirname(__file__))
template_path = path.join(package_dir, 'themes')
def get_path():
return template_path
.. versionadded:: 1.2
'sphinx_themes' entry_points feature.
.. _builtin-themes:

View File

@ -16,6 +16,11 @@ import tempfile
import ConfigParser
from os import path
try:
import pkg_resources
except ImportError:
pkg_resources = False
from sphinx import package_dir
from sphinx.errors import ThemeError
@ -59,10 +64,22 @@ class Theme(object):
tinfo = None
cls.themes[tname] = (path.join(themedir, theme), tinfo)
@classmethod
def load_extra_themes(cls):
for themedir in load_theme_plugins():
if not path.isdir(themedir):
continue
for theme in os.listdir(themedir):
if not path.isfile(path.join(themedir, theme, THEMECONF)):
continue
cls.themes[theme] = (path.join(themedir, theme), None)
def __init__(self, name):
if name not in self.themes:
raise ThemeError('no theme named %r found '
'(missing theme.conf?)' % name)
self.load_extra_themes()
if name not in self.themes:
raise ThemeError('no theme named %r found '
'(missing theme.conf?)' % name)
self.name = name
tdir, tinfo = self.themes[name]
@ -152,3 +169,29 @@ class Theme(object):
pass
if self.base:
self.base.cleanup()
def load_theme_plugins():
"""load plugins by using``sphinx_themes`` section in setuptools entry_points.
This API will return list of directory that contain some theme directory.
"""
if not pkg_resources:
return []
theme_paths = []
for plugin in pkg_resources.iter_entry_points('sphinx_themes'):
func_or_path = plugin.load()
try:
path = func_or_path()
except:
path = func_or_path
if isinstance(path, basestring):
theme_paths.append(path)
else:
raise ThemeError('Plugin %r does not response correctly.' %
plugin.module_name)
return theme_paths