Developer Reference

Python API Reference

In order to work, this extension adds a number of new classes and functions:

  • 1 domain - InlineReferenceDomain - through which all user-level interactions are exposed and which manages persistent data.

  • 4 roles within the domain, which allow users to create hyperlinks

    • :iref:ref: which is handled by RegisteredXRefRole

    • :iref:target: which is handled by ReferenceTargetRole

    • :iref:backlink: which is handled by BackLinkRole

    • :iref:mref: which is handled by MutualReferenceRole

  • 5 nodes created by the roles and which handle the creation of the links

    • inline_reference which identical to the docutils.nodes.reference class except for the LaTeX build system, and which handles the normal references, from :iref:ref: to :iref:target:

    • id_reference which is similar to docutils.nodes.reference, but which holds its own ID to be able to be hyperlinked to, and which is used in the references from :iref:ref: to :iref:backlink:

    • reference_target which is the simple target for hyperlinks and which is used to represent :iref:target:

    • backlink which is a new class for representing :iref:backlink:

    • mutual_ref which is a new class for working with :iref:mref:

  • 2 event hooks for the doctree-resolved event

    • process_mutual_reference_nodes for connecting the pairs of mutual_ref nodes, once all the nodes have been created.

    • process_backlink_nodes for connecting each backlink node to each id_reference node that links to it.

  • various visit_ and depart_ functions that implement the writing of each supported output format in the cases where the default implementations are not sufficient or similar enough functionality does not exist.

How This Works

Referencing a Normal Target

By creating a link from :iref:ref:name<id> to :iref:target:name<id>, two nodes are created in the middle of the paragraph: a sphinx.addnodes.pending_xref node for the reference, and a reference_target node for the target. On creation of the target, it is registered with the domain. Then, once the entire .rst document is read and all nodes are finished loading, sphinx starts resolving pending references, which calls the ReferenceDomain.resolve_xref method for each pending_xref node. The domain matches the id from the pending_xref to the appropriate target, using the saved information. An inline_reference node is created, which will replace the pending_xref node. This new node has the refid and refuri parameters set and pointing to the ids parameter of the reference_target node. All that happens after is that the writer for the selected format will appropriately use this information so that a hyperlink is created in the output.

Mutual References

By using :iref:mref:name<id> twice, with the same ID, two mutual_ref nodes are created in the middle of the paragraph. On creation of each, they are registered with the domain, in the mutual_refs dict. However, since the user provides only one ID, and two will be required under the hood (one for each node), the domain also creates a unique ID for each, which is immediately set to the ids parameter of the created nodes.

Then, once the tree for the document has been fully resolved, sphinx emits the doctree-resolved event and calls the process_mutual_reference_nodes function. This goes over each mutual_ref in the document and edits its refid and refuri parameters to point to the ID of the other corresponding mutual_ref node. All that happens after is that the writer for the selected format will appropriately use this information so that a hyperlink is created in the output.

class inline_reference.inline_reference.BackLinkRole

Bases: TargetRole

Role for creating a target that includes a link to each link that links to the target.

Methods

target_class

alias of backlink

target_class

alias of backlink

class inline_reference.inline_reference.InlineReferenceDomain(env: BuildEnvironment)

Bases: Domain

Methods

add_loose_reference(from_doc, target_signature)

Adds a RegisteredXRefRole to the domain.

add_mutual_reference(signature)

Adds a mutual reference (MutualReference) to the domain and generates a unique ID for the node.

add_reference_target(signature, code)

Adds a target reference (Target) to the domain.

resolve_xref(env, fromdocname, builder, typ, ...)

Resolves a pending xref node.

add_loose_reference(from_doc: str, target_signature: str) None

Adds a RegisteredXRefRole to the domain.

Saves the document in which the node is found and a unique ID to the domain data.

Parameters:
from_doc

The name of the document in which the node is found.

target_signature

The signature of the target that the reference points to.

add_mutual_reference(signature: str) str

Adds a mutual reference (MutualReference) to the domain and generates a unique ID for the node.

Saves the original signature of the node, the name of the document in which the node was found, and the new unique ID, to the domain data for mutual references.

The unique ID can be used do distinguish between the two mutual_ref nodes, since they are created using the same signature. This is an internal implementation detail required to make the hyperlinks work without placing undue effort on the users.

Parameters:
signature

The signature of the node - the code/label used to identify the target for the reference

Returns:
id

The unique ID for the node.

add_reference_target(signature: str, code: str) None

Adds a target reference (Target) to the domain.

Saves the signature of the node, the type of the target, and the document in which the node is found, to the domain data.

Parameters:
signature

The signature of the node - the code/label used to identify the target for the reference

code

The name of the type of target, e.g. ‘target’ or ‘backlink’.

data_version = 0

data version, bump this when the format of self.data changes

initial_data: dict[str, Any] = {'loose_refs': {}, 'mutual_refs': {}, 'targets': []}

data value for a fresh environment

label = 'Inline Reference'

domain label: longer, more descriptive (used in messages)

name = 'iref'

domain name: should be short, but unique

resolve_xref(env: BuildEnvironment, fromdocname: str, builder: Builder, typ: str, target: str, node: pending_xref, contnode: nodes.Element) id_reference | inline_reference | None

Resolves a pending xref node.

Creates a new node that will replace the pending xref node. This is done by matching the pending xref node to the appropriate target registered with the domain.

Parameters:
env

The build environment.

fromdocname

The name of the document in which node is found.

builder

The sphinx builder being used.

typ

The name of the pending xref node.

target

The code/label used to identify the target of the pending xref node.

node

The pending xref node.

contnode

The node containing the contents of the pending xref node.

Returns:
reference_node

The reference node with the target set. None is returned when a match cannot be found.

roles: dict[str, RoleFunction | XRefRole] = {'backlink': <inline_reference.inline_reference.BackLinkRole object>, 'mref': <inline_reference.inline_reference.MutualReferenceRole object>, 'ref': <inline_reference.inline_reference.RegisteredXRefRole object>, 'target': <inline_reference.inline_reference.ReferenceTargetRole object>}

role name -> role callable

class inline_reference.inline_reference.MutualReferenceRole

Bases: SphinxRole

Role for creating a mutual reference.

In this context, a mutual reference is a set of two references which link to each other.

Methods

run()

Creates a mutual_ref node and registers with the domain.

run() tuple[list[Node], list[system_message]]

Creates a mutual_ref node and registers with the domain.

class inline_reference.inline_reference.ReferenceTargetRole

Bases: TargetRole

Role for creating a target that looks like the text around it.

Methods

target_class

alias of reference_target

target_class

alias of reference_target

class inline_reference.inline_reference.RegisteredXRefRole(fix_parens: bool = False, lowercase: bool = False, nodeclass: type[Element] | None = None, innernodeclass: type[TextElement] | None = None, warn_dangling: bool = False)

Bases: XRefRole

A cross-referencing role that adds an entry to the domain registry.

Functionally identical to the default sphinx.roles.XRefRole, but with the addition that it integrates with the domain defined in this package. This is necessary to support the backlink functionality.

Methods

run()

Creates a pending reference node and registers the data with the domain.

run() tuple[list[Node], list[system_message]]

Creates a pending reference node and registers the data with the domain.

class inline_reference.inline_reference.TargetRole

Bases: SphinxRole

Base class for target roles, or roles specifically for being cross-linked to.

Subclasses should only specify the two new attributes.

Attributes:
target_class

Element is the superclass to all specific elements.

code

The code to use for the anchor and signature in the domain.

Methods

run()

Creates a target node - node with id so that it can be linked to.

target_class

alias of Element

run() tuple[list[Node], list[system_message]]

Creates a target node - node with id so that it can be linked to.

target_class

alias of Element

Bases: TextElement, Targetable, Inline, BackLinkable

Node that serves as an arbitrary target, while also containing hyperlinks to each hyperlink that links to it.

This node should act like normal text when not linked to, like mutual_ref when linked to once, and similar to a citation when linked to multiple times.

Depart backlink for HTML writer.

If the node contains fewer than 2 backrefs, the a HTML tag is simply closed. Otherwise, a series of subscript numbers, each containing a link to one of the backrefs, is created.

Depart backlink for LaTeX writer.

Similar to depart_backlink_node_html in that the LaTeX tag is simply closed for 0-1 backrefs, and for more, a list of subscript numbers hyperlinking to each hyperlink linking to the node, is created.

inline_reference.inline_reference.depart_mutual_ref_node_latex(self: NodeVisitor, node: mutual_ref) None

Departs the mutual_ref node for the LaTeX builder.

inline_reference.inline_reference.depart_reference_node_default(self: NodeVisitor, node: Node) None

Depart the default reference node in any builder.

A wrapper around the default depart_reference method. Used in this package for reference-like nodes where the default implementation is sufficient.

inline_reference.inline_reference.depart_reference_node_latex(self: NodeVisitor, _: reference) None

Depart the inline_reference node in the LaTeX builder.

inline_reference.inline_reference.depart_reference_target_node_html(self: NodeVisitor, _: reference_target) None

Depart reference_target for HTML writer.

inline_reference.inline_reference.depart_reference_target_node_latex(self: NodeVisitor, node: reference_target) None

Depart reference_target for LaTeX writer.

class inline_reference.inline_reference.id_reference(rawsource='', text='', *children, **attributes)

Bases: reference

A reference node that contains the ids parameter.

class inline_reference.inline_reference.inline_reference(rawsource='', text='', *children, **attributes)

Bases: reference

A reference node. Required for custom LaTeX writer.

inline_reference.inline_reference.make_refnode(builder: Builder, fromdocname: str, todocname: str, targetid: str | None, child: nodes.Node | list[nodes.Node], title: str | None = None, cls: type(nodes.reference) = <class 'docutils.nodes.reference'>) nodes.reference

Shortcut to create a reference node.

This function is mostly copied from the sphinx.utils package, but further contains the cls parameter allowing the specification of the particular docutils.nodes.reference subclass to create.

Parameters:
builder

The Sphinx builder that is being used.

fromdocname

The name of the document in which the reference lies. The origin of the link.

todocname

The name of the document in which the target lies. The target of the link.

targetid

The id of the target. Use for cross-referencing within a document. Only set if provided.

child

The children nodes of the node being made into a link. These nodes are added as children nodes to the created reference node.

title

The title of the reference. Only set if provided.

cls

The class to instantiate. The returned node will be of this type.

Returns:
reference_node

A reference node with ‘refid’, ‘refuri’, and ‘reftitle’ set (if these were provided).

class inline_reference.inline_reference.mutual_ref(rawsource='', text='', *children, **attributes)

Bases: General, BackLinkable, TextElement, Targetable, Inline

Node representing a text target to a reference while being a reference itself back.

In other words, this node is used to create two nodes with hyperlinks to each other. In effect a special case of the backlink node.

Processes all backlink nodes.

Iterates over all backlink nodes in the document and edits them so that they contain the backreferences to all nodes that link to them.

Parameters:
app

Sphinx app.

doctree

The document tree.

fromdocname

The name of the document calling this function.

inline_reference.inline_reference.process_mutual_reference_nodes(app: Sphinx, doctree: document, fromdocname: str) None

Processes all mutual reference nodes.

Iterates over all mutual_ref nodes in the document and edits them so that they link to their corresponding paired nodes.

Parameters:
app

Sphinx app.

doctree

The document tree.

fromdocname

The name of the document calling this function.

class inline_reference.inline_reference.reference_target(rawsource='', text='', *children, **attributes)

Bases: TextElement, Targetable, Inline

Node representing an arbitrary target for a reference.

This node is turned into the text it contains while containing some of form of anchor that allows the reference-like nodes to create hyperlinks with this node as the target.

inline_reference.inline_reference.replace_literal_nodes(children: Node | list[Node]) Node | list[Node]

Replaces all docutils.nodes.literal nodes amond children with docutils.nodes.Text nodes.

This function is used to correct the formatting of hyperlinks, which are at some point (incorrectly) formatted by sphinx as literals.

Parameters:
children

The node or nodes that need to be checked.

Returns:
new_children

The children with the literal nodes replaced by Text nodes.

inline_reference.inline_reference.setup(app: Sphinx) ExtensionMetadata

Plugs the extension into Sphinx.

Visit backlink for HTML writer.

Creates the a HTML tag with the contents of the node and the id parameter set to the id of the node. If the node contains 0 backrefs or more than 1 backref, little is done in this method - only a normal text with id set is created. Instead, most of the work is performed in the depart_backlink_node_html method.

Visit backlink for LaTeX writer.

Similar to visit_backlink_node_html, if 0 or more than 1 backrefs exist in the node, simply a \hypertarget is created for each id. Otherwise, the text itself is turned into a hyperlink and a hypertarget, similar to visit_mutual_ref_node_latex.

inline_reference.inline_reference.visit_mutual_ref_node_latex(self: NodeVisitor, node: mutual_ref) None

Visits the mutual_ref node for the LaTeX builder.

Creates a LaTeX hyperlink that also contains a hypertarget for each id that the node contains.

inline_reference.inline_reference.visit_reference_node_default(self: NodeVisitor, node: Node) None

Visit the default reference node in any builder.

A wrapper around the default visit_reference method. Used in this package for reference-like nodes where the default implementation is sufficient.

inline_reference.inline_reference.visit_reference_node_latex(self: NodeVisitor, node: reference) None

Visit the inline_reference node in the LaTeX builder.

Creates a LaTeX hyperlink with no hypertarget attached. Should create similar effect to the default implementation (which uses \hyperref), but this version has to supercede because \hyperref does not work with \hypertarget that this package relies on in LaTeX.

inline_reference.inline_reference.visit_reference_target_node_html(self: NodeVisitor, node: reference_target) None

Visit reference_target node in the HTML writer.

This method creates the a HTML tag that uses CSS such that the text does not appear like a hyperlink but like the surrounding text, but including the id property to allow the text to be hyperlinked to.

inline_reference.inline_reference.visit_reference_target_node_latex(self: NodeVisitor, node: reference_target) None

Visit reference_target for LaTeX writer.

Creates a \hypertarget value for each id in the node, with the text that appears in the document being the text in the node.