From a0e8f14085d80371ef149fae0c2ff446ffd72075 Mon Sep 17 00:00:00 2001 From: Rambaud Pierrick <12rambau@users.noreply.github.com> Date: Sat, 14 Jan 2023 14:52:00 +0100 Subject: [PATCH] ENH/MAINT: avoid overwriting the HtmlTranslator (#1105) Co-authored-by: Chris Holdgraf Fix https://github.com/pydata/pydata-sphinx-theme/issues/143 Fix https://github.com/pydata/pydata-sphinx-theme/issues/94 --- src/pydata_sphinx_theme/__init__.py | 47 +++++++++++++++---- ...strap_html_translator.py => translator.py} | 10 ++-- 2 files changed, 44 insertions(+), 13 deletions(-) rename src/pydata_sphinx_theme/{bootstrap_html_translator.py => translator.py} (86%) diff --git a/src/pydata_sphinx_theme/__init__.py b/src/pydata_sphinx_theme/__init__.py index d2b00101c..6fd5debde 100644 --- a/src/pydata_sphinx_theme/__init__.py +++ b/src/pydata_sphinx_theme/__init__.py @@ -6,6 +6,7 @@ from functools import lru_cache import json from urllib.parse import urlparse, urlunparse +import types import jinja2 from bs4 import BeautifulSoup as bs @@ -22,7 +23,7 @@ import requests from requests.exceptions import ConnectionError, HTTPError, RetryError -from .bootstrap_html_translator import BootstrapHTML5Translator +from .translator import BootstrapHTML5TranslatorMixin __version__ = "0.12.1rc1.dev0" @@ -1047,6 +1048,42 @@ def parse_url(self, uri): return text +def setup_translators(app): + """ + Add bootstrap HTML functionality if we are using an HTML translator. + + This re-uses the pre-existing Sphinx translator and adds extra functionality defined + in ``BootstrapHTML5TranslatorMixin``. This way we can retain the original translator's + behavior and configuration, and _only_ add the extra bootstrap rules. + If we don't detect an HTML-based translator, then we do nothing. + """ + if not app.registry.translators.items(): + translator = types.new_class( + "BootstrapHTML5Translator", + ( + BootstrapHTML5TranslatorMixin, + app.builder.default_translator_class, + ), + {}, + ) + app.set_translator(app.builder.name, translator, override=True) + else: + for name, klass in app.registry.translators.items(): + if app.builder.format != "html": + # Skip translators that are not HTML + continue + + translator = types.new_class( + "BootstrapHTML5Translator", + ( + BootstrapHTML5TranslatorMixin, + klass, + ), + {}, + ) + app.set_translator(name, translator, override=True) + + # ----------------------------------------------------------------------------- @@ -1058,13 +1095,7 @@ def setup(app): app.add_post_transform(ShortenLinkTransform) - app.set_translator("html", BootstrapHTML5Translator) - # Read the Docs uses ``readthedocs`` as the name of the build, and also - # uses a special "dirhtml" builder so we need to replace these both with - # our custom HTML builder - app.set_translator("readthedocs", BootstrapHTML5Translator, override=True) - app.set_translator("readthedocsdirhtml", BootstrapHTML5Translator, override=True) - + app.connect("builder-inited", setup_translators) app.connect("builder-inited", update_config) app.connect("html-page-context", setup_edit_url) app.connect("html-page-context", add_toctree_functions) diff --git a/src/pydata_sphinx_theme/bootstrap_html_translator.py b/src/pydata_sphinx_theme/translator.py similarity index 86% rename from src/pydata_sphinx_theme/bootstrap_html_translator.py rename to src/pydata_sphinx_theme/translator.py index 460b127e6..3c9ef46a9 100644 --- a/src/pydata_sphinx_theme/bootstrap_html_translator.py +++ b/src/pydata_sphinx_theme/translator.py @@ -1,18 +1,18 @@ -"""A custom Sphinx HTML Translator for Bootstrap layout +""" +A custom Sphinx HTML Translator for Bootstrap layout """ from packaging.version import Version import sphinx -from sphinx.writers.html5 import HTML5Translator from sphinx.util import logging from sphinx.ext.autosummary import autosummary_table logger = logging.getLogger(__name__) -class BootstrapHTML5Translator(HTML5Translator): - """Custom HTML Translator for a Bootstrap-ified Sphinx layout - This is a specialization of the HTML5 Translator of sphinx. +class BootstrapHTML5TranslatorMixin: + """ + Mixin HTML Translator for a Bootstrap-ified Sphinx layout. Only a couple of functions have been overridden to produce valid HTML to be directly styled with Bootstrap, and fulfill acessibility best practices. """