diff options
author | shimizukawa <shimizukawa@gmail.com> | 2013-09-16 23:57:58 +0900 |
---|---|---|
committer | shimizukawa <shimizukawa@gmail.com> | 2013-09-16 23:57:58 +0900 |
commit | 4f10b03d228f6453d4ba7cc27eb5a1236e710394 (patch) | |
tree | 785bb86320595925ccc132a7d0a58889c936342a | |
parent | 0f6902e6f88b198cf8ee815d11bae6268084f695 (diff) | |
download | sphinx-4f10b03d228f6453d4ba7cc27eb5a1236e710394.tar.gz |
Add feature: theme package collection by using setuptools plugin mechanism.
-rw-r--r-- | CHANGES | 1 | ||||
-rw-r--r-- | doc/theming.rst | 29 | ||||
-rw-r--r-- | sphinx/theming.py | 47 |
3 files changed, 74 insertions, 3 deletions
@@ -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 -------------------- diff --git a/doc/theming.rst b/doc/theming.rst index 0375bc71..771dfb96 100644 --- a/doc/theming.rst +++ b/doc/theming.rst @@ -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: diff --git a/sphinx/theming.py b/sphinx/theming.py index dd20aa2b..c7f73478 100644 --- a/sphinx/theming.py +++ b/sphinx/theming.py @@ -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 |