From 7f55f21a60552fc096ec12111e76bf5acf763ce4 Mon Sep 17 00:00:00 2001 From: Jared Dillard Date: Fri, 6 Mar 2026 18:46:14 -0800 Subject: [PATCH 1/3] Support external theme packages for SCSS compilation Refactor SCSS folder resolution to use a method that imports the theme module and retrieves the SCSS sources path, with a fallback to the bundled theme. --- sphinx_simplepdf/builders/simplepdf.py | 37 +++++++++++++++++++------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/sphinx_simplepdf/builders/simplepdf.py b/sphinx_simplepdf/builders/simplepdf.py index 509b486..6925b79 100644 --- a/sphinx_simplepdf/builders/simplepdf.py +++ b/sphinx_simplepdf/builders/simplepdf.py @@ -1,3 +1,4 @@ +import importlib import os import re import subprocess @@ -55,15 +56,7 @@ def __init__(self, *args, **kwargs): # Generate main.css logger.info("Generating css files from scss-templates") css_folder = os.path.join(self.app.outdir, "_static") - scss_folder = os.path.join( - os.path.dirname(__file__), - "..", - "themes", - "simplepdf_theme", - "static", - "styles", - "sources", - ) + scss_folder = self._resolve_scss_folder() sass.compile( dirname=(scss_folder, css_folder), output_style="nested", @@ -105,6 +98,32 @@ def get_theme_option_var(self, name, default): return default return simplepdf_theme_options[name] + def _resolve_scss_folder(self): + """Resolve the SCSS sources folder from the configured theme package. + + Tries to import the theme module specified by simplepdf_theme and use + its get_scss_sources_path() if available. Falls back to the bundled + simplepdf_theme if the external theme cannot be found. + """ + theme_name = self.app.config.simplepdf_theme or "simplepdf_theme" + try: + theme_module = importlib.import_module(theme_name) + if hasattr(theme_module, "get_scss_sources_path"): + return theme_module.get_scss_sources_path() + return os.path.join( + os.path.dirname(theme_module.__file__), + "static", "styles", "sources", + ) + except ImportError: + logger.info( + f"Could not import theme '{theme_name}', " + "falling back to bundled simplepdf_theme" + ) + return os.path.join( + os.path.dirname(__file__), "..", "themes", + "simplepdf_theme", "static", "styles", "sources", + ) + def finish(self) -> None: super().finish() From f42b4378523c4f8f0703689e56864349dedc40d9 Mon Sep 17 00:00:00 2001 From: Jared Dillard Date: Tue, 10 Mar 2026 12:18:58 -0700 Subject: [PATCH 2/3] Improve support for external theme packages by using a get_scss_sources_path() convention --- docs/changelog.rst | 8 ++++++ docs/configuration.rst | 28 ++++++++++++++++++- pyproject.toml | 2 +- sphinx_simplepdf/builders/simplepdf.py | 26 +++++++++-------- .../themes/simplepdf_theme/__init__.py | 5 ++++ 5 files changed, 55 insertions(+), 14 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 97268e8..919cd48 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,14 @@ Changelog ========= +Release 1.8 +----------- +:released: unreleased + +* **Bugfix**: Improve support for external theme packages by using a ``get_scss_sources_path()`` convention. + + - If needed, theme warnings can be suppressed via ``suppress_warnings = ["simplepdf.theme"]``. + Release 1.7 ----------- :released: 02.12.2025 diff --git a/docs/configuration.rst b/docs/configuration.rst index 233c40e..7cb01bd 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -166,7 +166,33 @@ simplepdf_theme --------------- .. versionadded:: 1.5 -Add custom theme for simplepdf. This overrides the default theme ``simplepdf_theme`` +Name of the theme to use for PDF output. This overrides the default theme ``simplepdf_theme``. +The value must match both the Sphinx theme name and the importable Python module name. + +.. code-block:: python + + simplepdf_theme = "my_custom_pdf_theme" + +The theme module must define a ``get_scss_sources_path()`` function that returns +the absolute path to its SCSS sources directory. This is how the builder locates +the SCSS files to compile into CSS for the PDF. + +**Minimal example:** + +.. code-block:: python + + from os import path + + def get_scss_sources_path(): + """Return the absolute path to the SCSS sources directory.""" + return path.join(path.abspath(path.dirname(__file__)), "static", "styles", "sources") + +The SCSS sources directory should contain a ``main.scss`` file as the entry point. +You can use the bundled ``simplepdf_theme`` as a reference for the expected +directory structure and SCSS files. + +.. note:: If the theme module cannot be imported or does not define ``get_scss_sources_path()``, + the builder falls back to the bundled ``simplepdf_theme`` SCSS sources and emits a warning. .. _theme_options: diff --git a/pyproject.toml b/pyproject.toml index e242d24..0735b33 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi" [project] name = "sphinx-simplepdf" -version = "1.7.0" +version = "1.8.0" description = "An easy to use PDF Builder for Sphinx with a modern PDF-Theme." readme = "README.rst" license = "MIT" diff --git a/sphinx_simplepdf/builders/simplepdf.py b/sphinx_simplepdf/builders/simplepdf.py index 6925b79..a88f943 100644 --- a/sphinx_simplepdf/builders/simplepdf.py +++ b/sphinx_simplepdf/builders/simplepdf.py @@ -101,28 +101,30 @@ def get_theme_option_var(self, name, default): def _resolve_scss_folder(self): """Resolve the SCSS sources folder from the configured theme package. - Tries to import the theme module specified by simplepdf_theme and use - its get_scss_sources_path() if available. Falls back to the bundled - simplepdf_theme if the external theme cannot be found. + Imports the theme module and calls its get_scss_sources_path(). Falls + back to the bundled simplepdf_theme if the theme cannot be imported or + does not define get_scss_sources_path(). """ theme_name = self.app.config.simplepdf_theme or "simplepdf_theme" try: theme_module = importlib.import_module(theme_name) if hasattr(theme_module, "get_scss_sources_path"): return theme_module.get_scss_sources_path() - return os.path.join( - os.path.dirname(theme_module.__file__), - "static", "styles", "sources", + logger.warning( + f"Theme '{theme_name}' does not define get_scss_sources_path(), " + "falling back to bundled simplepdf_theme", + type="simplepdf", + subtype="theme", ) except ImportError: - logger.info( + logger.warning( f"Could not import theme '{theme_name}', " - "falling back to bundled simplepdf_theme" - ) - return os.path.join( - os.path.dirname(__file__), "..", "themes", - "simplepdf_theme", "static", "styles", "sources", + "falling back to bundled simplepdf_theme", + type="simplepdf", + subtype="theme", ) + from sphinx_simplepdf.themes.simplepdf_theme import get_scss_sources_path + return get_scss_sources_path() def finish(self) -> None: super().finish() diff --git a/sphinx_simplepdf/themes/simplepdf_theme/__init__.py b/sphinx_simplepdf/themes/simplepdf_theme/__init__.py index 8a873f5..bbc3bcd 100644 --- a/sphinx_simplepdf/themes/simplepdf_theme/__init__.py +++ b/sphinx_simplepdf/themes/simplepdf_theme/__init__.py @@ -14,6 +14,11 @@ def get_html_theme_path(): return cur_dir +def get_scss_sources_path(): + """Return the absolute path to the SCSS sources directory.""" + return path.join(path.abspath(path.dirname(__file__)), "static", "styles", "sources") + + # See http://www.sphinx-doc.org/en/stable/theming.html#distribute-your-theme-as-a-python-package def setup(app): app.add_html_theme("simplepdf_theme", path.abspath(path.dirname(__file__))) From 4c8e24493980163cee81a0e0a2ab7315d40d22de Mon Sep 17 00:00:00 2001 From: Jared Dillard Date: Tue, 10 Mar 2026 12:54:48 -0700 Subject: [PATCH 3/3] Add PR reference to changelog bugfix entry --- docs/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 919cd48..a1c923d 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,7 +5,7 @@ Release 1.8 ----------- :released: unreleased -* **Bugfix**: Improve support for external theme packages by using a ``get_scss_sources_path()`` convention. +* **Bugfix**: [#134] Improve support for external theme packages by using a ``get_scss_sources_path()`` convention. - If needed, theme warnings can be suppressed via ``suppress_warnings = ["simplepdf.theme"]``.