How to hook into sphinx.writers.html5.HTML5Translator.add_permalink_ref() to add custom HTML to every heading?

98 views
Skip to first unread message

Nico Gulden

unread,
Oct 10, 2022, 10:53:56 AM10/10/22
to sphinx...@googlegroups.com
Hello Sphinx Community,

I'd like to add something similar like the permanent link anchor to
every heading in the HTML build of my Sphinx documents.

I use a custom theme based on the fabulous Sphinx Book Theme which
depends on the great PyData Sphinx Theme.

And I use and an extension that sets a custom translator:

app.set_translator(
"html",
MyTranslator,
)

And in MyTranslator, I say:


from pydata_sphinx_theme.bootstrap_html_translator import
BootstrapHTML5Translator as Translator

class MyTranslator(Translator):

def add_feedback_link(self, node: Element, title: str) -> None:
content = "some HTML"
self.body.append(content)

def add_permalink_ref(self, node: Element, title: str) -> None:
"""
super().add_permalink_ref(node, title)
self.add_feedback_link(
node, _("Feel free to provide feedback on this section.")
)

I overwrite the add_permalink_ref() method from
sphinx.writers.html5.HTML5Translator, so that it calls my
add_feedback_link() method.


The problem is the following traceback:

Traceback (most recent call last):
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/cmd/build.py",
line 272, in build_main
app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/application.py",
line 256, in __init__
self._init_builder()
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/application.py",
line 314, in _init_builder
self.builder.init()
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/builders/html/__init__.py",
line 212, in init
self.init_templates()
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/builders/html/__init__.py",
line 260, in init_templates
self.theme = theme_factory.create(themename)
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/theming.py", line
243, in create
return Theme(name, self.themes[name], factory=self)
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/theming.py", line
78, in __init__
self.base = factory.create(inherit)
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/theming.py", line
243, in create
return Theme(name, self.themes[name], factory=self)
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/theming.py", line
78, in __init__
self.base = factory.create(inherit)
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/theming.py", line
232, in create
self.load_extra_theme(name)
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/theming.py", line
177, in load_extra_theme
self.load_external_theme(name)
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/theming.py", line
202, in load_external_theme
self.app.registry.load_extension(self.app, entry_point.module)
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/registry.py", line
438, in load_extension
metadata = setup(app)
File
".virtualenvs/docs/lib/python3.9/site-packages/pydata_sphinx_theme/__init__.py",
line 559, in setup
app.set_translator("html", BootstrapHTML5Translator)
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/application.py",
line 541, in set_translator
self.registry.add_translator(name, translator_class, override=override)
File
".virtualenvs/docs/lib/python3.9/site-packages/sphinx/registry.py", line
309, in add_translator
raise ExtensionError(__('Translator for %r already exists') % name)
sphinx.errors.ExtensionError: Translator for 'html' already exists

Extension error:
Translator for 'html' already exists

The reason is that two translators with the name "html" are defined. One
from my extension and one from PyData Sphinx Theme. And the translator
from PyData Sphinx Theme doesn't override the translator. If it would
override, my customization isn't applied.

https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.set_translator

I don't necessarily want to override the translator, if there is another
way to hook into the process and add some html code to every heading. I
couldn't find something in the documentation.

I just want to hook into the add_permalink_ref() method to add my custom
code.

Does anybody have another idea?

I appreciate any pointer to documentation or other source code where you
achieve something similar.

Best regards,
Nico

--
Nico Gulden
E-Mail: ngu...@gmx.de
1024D/B2691D50 5415 501F AC07 D04A EB03 D01C 786D 966B B269 1D50

Hardware runs the world, software controls the hardware,
code generates the software, have you coded today?
OpenPGP_signature

Nico Gulden

unread,
Oct 27, 2022, 9:55:34 AM10/27/22
to sphinx...@googlegroups.com
Hello Sphinx community,

I successfully solved the issue by myself.

In the setup() method of my extension I make sure that the other
extension loads first with:

app.setup_extension("pydata_sphinx_theme")

And then later in my setup, I have

app.set_translator(
"html",
MyTranslator,
override=True,
)

This make sure that Sphinx sets up the extension in a non-conflicting
order for my extension. Now it works.

Best regards,
Nico

Am 10.10.22 um 16:53 schrieb Nico Gulden:
OpenPGP_signature
Reply all
Reply to author
Forward
0 new messages