diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:25:40 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 17:25:40 +0000 |
commit | cf7da1843c45a4c2df7a749f7886a2d2ba0ee92a (patch) | |
tree | 18dcde1a8d1f5570a77cd0c361de3b490d02c789 /sphinx/builders/latex/theming.py | |
parent | Initial commit. (diff) | |
download | sphinx-cf7da1843c45a4c2df7a749f7886a2d2ba0ee92a.tar.xz sphinx-cf7da1843c45a4c2df7a749f7886a2d2ba0ee92a.zip |
Adding upstream version 7.2.6.upstream/7.2.6
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sphinx/builders/latex/theming.py')
-rw-r--r-- | sphinx/builders/latex/theming.py | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/sphinx/builders/latex/theming.py b/sphinx/builders/latex/theming.py new file mode 100644 index 0000000..21b49e8 --- /dev/null +++ b/sphinx/builders/latex/theming.py @@ -0,0 +1,135 @@ +"""Theming support for LaTeX builder.""" + +from __future__ import annotations + +import configparser +from os import path +from typing import TYPE_CHECKING + +from sphinx.errors import ThemeError +from sphinx.locale import __ +from sphinx.util import logging + +if TYPE_CHECKING: + from sphinx.application import Sphinx + from sphinx.config import Config + +logger = logging.getLogger(__name__) + + +class Theme: + """A set of LaTeX configurations.""" + + LATEX_ELEMENTS_KEYS = ['papersize', 'pointsize'] + UPDATABLE_KEYS = ['papersize', 'pointsize'] + + def __init__(self, name: str) -> None: + self.name = name + self.docclass = name + self.wrapperclass = name + self.papersize = 'letterpaper' + self.pointsize = '10pt' + self.toplevel_sectioning = 'chapter' + + def update(self, config: Config) -> None: + """Override theme settings by user's configuration.""" + for key in self.LATEX_ELEMENTS_KEYS: + if config.latex_elements.get(key): + value = config.latex_elements[key] + setattr(self, key, value) + + for key in self.UPDATABLE_KEYS: + if key in config.latex_theme_options: + value = config.latex_theme_options[key] + setattr(self, key, value) + + +class BuiltInTheme(Theme): + """A built-in LaTeX theme.""" + + def __init__(self, name: str, config: Config) -> None: + super().__init__(name) + + if name == 'howto': + self.docclass = config.latex_docclass.get('howto', 'article') + else: + self.docclass = config.latex_docclass.get('manual', 'report') + + if name in ('manual', 'howto'): + self.wrapperclass = 'sphinx' + name + else: + self.wrapperclass = name + + # we assume LaTeX class provides \chapter command except in case + # of non-Japanese 'howto' case + if name == 'howto' and not self.docclass.startswith('j'): + self.toplevel_sectioning = 'section' + else: + self.toplevel_sectioning = 'chapter' + + +class UserTheme(Theme): + """A user defined LaTeX theme.""" + + REQUIRED_CONFIG_KEYS = ['docclass', 'wrapperclass'] + OPTIONAL_CONFIG_KEYS = ['papersize', 'pointsize', 'toplevel_sectioning'] + + def __init__(self, name: str, filename: str) -> None: + super().__init__(name) + self.config = configparser.RawConfigParser() + self.config.read(path.join(filename), encoding='utf-8') + + for key in self.REQUIRED_CONFIG_KEYS: + try: + value = self.config.get('theme', key) + setattr(self, key, value) + except configparser.NoSectionError as exc: + raise ThemeError(__('%r doesn\'t have "theme" setting') % + filename) from exc + except configparser.NoOptionError as exc: + raise ThemeError(__('%r doesn\'t have "%s" setting') % + (filename, exc.args[0])) from exc + + for key in self.OPTIONAL_CONFIG_KEYS: + try: + value = self.config.get('theme', key) + setattr(self, key, value) + except configparser.NoOptionError: + pass + + +class ThemeFactory: + """A factory class for LaTeX Themes.""" + + def __init__(self, app: Sphinx) -> None: + self.themes: dict[str, Theme] = {} + self.theme_paths = [path.join(app.srcdir, p) for p in app.config.latex_theme_path] + self.config = app.config + self.load_builtin_themes(app.config) + + def load_builtin_themes(self, config: Config) -> None: + """Load built-in themes.""" + self.themes['manual'] = BuiltInTheme('manual', config) + self.themes['howto'] = BuiltInTheme('howto', config) + + def get(self, name: str) -> Theme: + """Get a theme for given *name*.""" + if name in self.themes: + theme = self.themes[name] + else: + theme = self.find_user_theme(name) or Theme(name) + + theme.update(self.config) + return theme + + def find_user_theme(self, name: str) -> Theme | None: + """Find a theme named as *name* from latex_theme_path.""" + for theme_path in self.theme_paths: + config_path = path.join(theme_path, name, 'theme.conf') + if path.isfile(config_path): + try: + return UserTheme(name, config_path) + except ThemeError as exc: + logger.warning(exc) + + return None |