[Python] Add additional class to Interpreted Text Roles in Sphinx

Discussão em 'Python' iniciado por Stack, Junho 6, 2025.

  1. Stack

    Stack Membro Participativo

    What I am trying to achieve is to (manually) insert a html-class to certain elements using sphinx' python domain

    For example I have this string:

    Lore Ipsum :py:mod:`dataclasses`


    Which results in:

    Lore Ipsum <a class="reference external" href="...dataclasses.html#module-dataclasses">
    <code class="xref py py-mod docutils literal notranslate">
    <span class="pre">dataclass</span>
    </code>
    </a>


    To either the a tag or code.class I would like to add an additional class. e.g. "injected", to have the following result

    <code class="xref py py-mod docutils literal notranslate injected">


    Some research I did to find a solution

    "Inherit" role


    .. role : injected_mod(?py:mod?)
    :class: injected

    :injected_mod:`dataclasses`


    Problem: I do not know what to put into the brackets, I think I cannot use domains there -> Not a valid role.

    Register a new role ❌


    Possible but, Problem: I want to keep the functionality from the py domain.

    Add role to :py: domain ❓


    # conf.py
    def setup():
    app.add_role_to_domain("py", "injected", PyXRefRole())


    What works: Adds a "py-injected" class that I could work with
    Problem?: The lookup feature and linking does not work to py:module, i.e. no <a class="reference external" is added. I haven't been able to determine where in the sphinx module the lookup feature takes place and if it possible to extend the PyXRefRole to do both.

    Nested Parsing/Roles (nearly)


    The question of composing roles is similar and provides a useful answer in the comboroles extension.

    This is somewhat nice as I can combine it with a role directive to add the class.

    :inject:`:py:mod:\`dataclasses\``


    Problem: This adds an extra <span class=injected> around the resulting block from py:mod, instead of modifying the existing tags.


    I am not sure if nested parsing is somewhat overkill, but so far I have not found a solution to add an additional class.
    I think using comboroles looks the most promising currently to continue with, but I am not yet sure how to extend it or port its utility to a custom role_function that injects a class instead of nesting an additional tag. I guess I need to access and modify to nodes in a custom function, but this is where I am stuck.

    Notes:

    • I know this is somewhat easy using MyST parsing, but currently I cannot parse this text globally via MyST.

    Continue reading...

Compartilhe esta Página