Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sphinx-doc/sphinx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2017-04-20 14:19:55 +0300
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2017-04-20 14:45:44 +0300
commitfaefe2b5a522763e918ae1ad67b02ae0bcde824f (patch)
treebf5b21e60212186974b1124ef2dd31e6c85e2ca5 /sphinx/theming.py
parentb405c0aaf52840e370a1ed6c88ab122fb1df644d (diff)
Add HTMLThemeFactory class
Diffstat (limited to 'sphinx/theming.py')
-rw-r--r--sphinx/theming.py133
1 files changed, 71 insertions, 62 deletions
diff --git a/sphinx/theming.py b/sphinx/theming.py
index abb99d1c8..fbd4dbb62 100644
--- a/sphinx/theming.py
+++ b/sphinx/theming.py
@@ -30,12 +30,13 @@ logger = logging.getLogger(__name__)
if False:
# For type annotation
from typing import Any, Dict, Iterator, List, Tuple # NOQA
+ from sphinx.application import Sphinx # NOQA
NODEFAULT = object()
THEMECONF = 'theme.conf'
-class _Theme(object):
+class Theme(object):
def __init__(self):
# type: () -> None
self.name = None
@@ -126,69 +127,56 @@ def is_archived_theme(filename):
return False
-def find_theme_entries(themedir):
- # type: (unicode) -> Iterator[Tuple[unicode, unicode]]
- for entry in os.listdir(themedir):
- pathname = path.join(themedir, entry)
- if path.isfile(pathname) and entry.lower().endswith('.zip'):
- if is_archived_theme(pathname):
- name = entry[:-4]
- yield name, pathname
- else:
- logger.warning(_('file %r on theme path is not a valid '
- 'zipfile or contains no theme'), entry)
- else:
- if path.isfile(path.join(pathname, THEMECONF)):
- yield entry, pathname
+class HTMLThemeFactory(object):
+ """A factory class for HTML Themes."""
+ def __init__(self, app):
+ # type: (Sphinx) -> None
+ self.confdir = app.confdir
+ self.themes = app.html_themes
+ self.load_builtin_themes()
+ if getattr(app.config, 'html_theme_path', None):
+ self.load_additional_themes(app.config.html_theme_path)
-class Theme(object):
- """
- Represents the theme chosen in the configuration.
- """
- themes = {} # type: Dict[unicode, unicode]
-
- @classmethod
- def init_themes(cls, confdir, theme_path):
- # type: (unicode, unicode) -> None
- """Search all theme paths for available themes."""
- themepath = list(theme_path)
- themepath.append(path.join(package_dir, 'themes'))
-
- # search themes from theme_paths
- for themedir in themepath:
- themedir = path.abspath(path.join(confdir, themedir))
- if not path.isdir(themedir):
- continue
- else:
- for name, theme in find_theme_entries(themedir):
- cls.themes[name] = theme
+ def load_builtin_themes(self):
+ # type: () -> None
+ themes = self.find_themes(path.join(package_dir, 'themes'))
+ for name, theme in iteritems(themes):
+ self.themes[name] = theme
+
+ def load_additional_themes(self, theme_paths):
+ # type: (unicode) -> None
+ for theme_path in theme_paths:
+ abs_theme_path = path.abspath(path.join(self.confdir, theme_path))
+ themes = self.find_themes(abs_theme_path)
+ for name, theme in iteritems(themes):
+ self.themes[name] = theme
- @classmethod
- def load_extra_theme(cls, name):
+ def load_extra_theme(self, name):
+ # type: (unicode) -> None
if name == 'alabaster':
- cls.load_alabaster()
+ self.load_alabaster_theme()
elif name == 'sphinx_rtd_theme':
- cls.load_sphinx_rtd_theme()
+ self.load_sphinx_rtd_theme()
else:
- pass
+ self.load_external_theme(name)
- @classmethod
- def load_alabaster(cls):
+ def load_alabaster_theme(self):
+ # type: () -> None
import alabaster
- cls.themes['alabaster'] = path.join(alabaster.get_path(), 'alabaster')
+ self.themes['alabaster'] = path.join(alabaster.get_path(), 'alabaster')
- @classmethod
- def load_sphinx_rtd_theme(cls):
+ def load_sphinx_rtd_theme(self):
+ # type: () -> None
try:
import sphinx_rtd_theme
- cls.themes['sphinx_rtd_theme'] = path.join(sphinx_rtd_theme.get_html_theme_path(),
- 'sphinx_rtd_theme')
+ theme_path = sphinx_rtd_theme.get_html_theme_path()
+ self.themes['sphinx_rtd_theme'] = path.join(theme_path, 'sphinx_rtd_theme')
except ImportError:
pass
- @classmethod
- def load_external_themes(cls, name):
+ def load_external_themes(self, name):
+ # type: (unicode) -> None
for entry_point in pkg_resources.iter_entry_points('sphinx_themes'):
target = entry_point.load()
if callable(target):
@@ -199,17 +187,38 @@ class Theme(object):
else:
themedir = target
- for entry, theme in find_theme_entries(themedir):
+ themes = self.find_themes(themedir)
+ for entry, theme in iteritems(themes):
if name == entry:
- cls.themes[entry] = theme
+ self.themes[name] = theme
+
+ def find_themes(self, theme_path):
+ # type: (unicode) -> Dict[unicode, unicode]
+ themes = {}
+ if not path.isdir(theme_path):
+ return themes
+
+ for entry in os.listdir(theme_path):
+ pathname = path.join(theme_path, entry)
+ if path.isfile(pathname) and entry.lower().endswith('.zip'):
+ if is_archived_theme(pathname):
+ name = entry[:-4]
+ themes[name] = pathname
+ else:
+ logger.warning(_('file %r on theme path is not a valid '
+ 'zipfile or contains no theme'), entry)
+ else:
+ if path.isfile(path.join(pathname, THEMECONF)):
+ themes[entry] = pathname
- @classmethod
- def create(cls, name):
- # type: (unicode) -> None
- if name not in cls.themes:
- cls.load_extra_theme(name)
+ return themes
+
+ def create(self, name):
+ # type: (unicode) -> Theme
+ if name not in self.themes:
+ self.load_extra_theme(name)
- if name not in cls.themes:
+ if name not in self.themes:
if name == 'sphinx_rtd_theme':
raise ThemeError(_('sphinx_rtd_theme is no longer a hard dependency '
'since version 1.4.0. Please install it manually.'
@@ -218,10 +227,10 @@ class Theme(object):
raise ThemeError(_('no theme named %r found '
'(missing theme.conf?)') % name)
- theme = _Theme()
+ theme = Theme()
theme.name = name
- themedir = cls.themes[name]
+ themedir = self.themes[name]
if path.isdir(themedir):
# already a directory, do nothing
theme.rootdir = None
@@ -253,10 +262,10 @@ class Theme(object):
if inherit == 'none':
theme.base = None
- elif inherit not in cls.themes:
+ elif inherit not in self.themes:
raise ThemeError('no theme named %r found, inherited by %r' %
(inherit, name))
else:
- theme.base = cls.create(inherit)
+ theme.base = self.create(inherit)
return theme