Automatic links from code examples to reference documentation.
npx @tessl/cli install tessl/pypi-sphinx-codeautolink@0.17.0A Sphinx extension that automatically creates clickable links from individual code elements in documentation examples to their corresponding reference documentation. It operates by parsing Python code blocks in documentation, analyzing the syntax tree to identify functions, classes, and other code elements, then automatically generating hyperlinks to the appropriate sections of the API documentation.
pip install sphinx-codeautolinksphinx>=3.2.0, beautifulsoup4>=4.8.1ipython!=8.7.0 (for IPython support)import sphinx_codeautolinkFor extension setup (in conf.py):
extensions = [
'sphinx_codeautolink',
# other extensions...
]Add to your Sphinx conf.py:
# Enable the extension
extensions = [
'sphinx_codeautolink',
'sphinx.ext.autodoc', # Required dependency
]
# Optional configuration
codeautolink_autodoc_inject = True
codeautolink_warn_on_missing_inventory = True
codeautolink_warn_on_failed_resolve = True.. autolink-examples:: MyClass
:collapse:
.. autolink-preface::
import numpy as np
import matplotlib.pyplot as plt
.. code-block:: python
# This code block will automatically get links
data = np.array([1, 2, 3, 4, 5])
plt.plot(data)
plt.show()
.. autolink-skip::
.. code-block:: python
# This code block will not get automatic links
print("No links here")The extension follows Sphinx's event-driven architecture and operates through several key phases:
Core components include the AST-based parser for Python code analysis, the inventory resolver for mapping names to documentation URLs, and the HTML post-processor for link injection.
Core extension functionality including the main setup function, configuration values, and extension lifecycle management.
def setup(app: Sphinx) -> dict[str, Any]:
"""Set up extension, directives and events."""
# Configuration values for conf.py
# codeautolink_autodoc_inject: bool = False
# codeautolink_global_preface: str = ""
# codeautolink_custom_blocks: dict = {}
# codeautolink_concat_default: bool = False
# codeautolink_search_css_classes: list = []
# codeautolink_inventory_map: dict = {}
# codeautolink_warn_on_missing_inventory: bool = False
# codeautolink_warn_on_failed_resolve: bool = False
# codeautolink_warn_on_no_backreference: bool = False
# codeautolink_warn_on_default_parse_fail: bool = FalseCustom Sphinx directives for controlling link generation behavior, including example display, code concatenation, prefacing, and selective skipping.
# Available directives:
# .. autolink-examples:: <object_name>
# .. autolink-concat:: [on|off|section]
# .. autolink-preface:: [level]
# .. autolink-skip:: [next|section|file|off]Code block analysis and transformation system that parses Python code, identifies name usage patterns, and prepares them for link generation.
def parse_names(source: str, doctree_node) -> list[Name]:
"""Parse names from Python source code."""
def clean_pycon(source: str) -> tuple[str, str]:
"""Clean up Python console syntax to pure Python."""
def clean_ipython(source: str) -> tuple[str, str]:
"""Clean up IPython magics and console syntax to pure Python."""System for resolving code names and imports to their documentation locations using Sphinx inventory data and intersphinx references.
def resolve_location(chain: Name, inventory) -> str:
"""Resolve a name chain to its final documented location."""
class CouldNotResolve(Exception):
"""Exception raised when name resolution fails."""class Name:
"""A name accessed in source traced back to an import."""
import_components: list[str]
code_str: str
lineno: int
end_lineno: int
context: LinkContext | None = None
resolved_location: str | None = None
class Component:
"""Name access component."""
name: str
lineno: int
end_lineno: int
context: str
class Access:
"""Accessed import whose tail is about to be recorded as a Name."""
context: LinkContext
prior_components: list[Component]
components: list[Component]class LinkContext(str, Enum):
"""Context in which a link appears to help HTML matching."""
none = "none"
after_call = "after_call"
import_from = "import_from"
import_target = "import_target"
class NameBreak(str, Enum):
"""Elements that break name access chains."""
call = "()"
namedexpr = ":="
import_from = ">"class SphinxCodeAutoLink:
"""Provide functionality and manage state between events."""
def build_inited(self, app) -> None: ...
def autodoc_process_docstring(self, app, what, name, obj, options, lines) -> None: ...
def parse_blocks(self, app, doctree) -> None: ...
def create_references(self, app, env) -> None: ...
def generate_backref_tables(self, app, doctree, docname): ...
def apply_links(self, app, exception) -> None: ...