Skip to main content

pymdown-symbolic-snippets

Extension that makes pymdownx.snippets symbol-aware.

Migration

  • Canonical package/distribution name is now pymdown-symbolic-snippets.
  • Canonical Python module path is now pymdown_symbolic_snippets.
  • Compatibility aliases remain for one release: zensical_symbolic_snippets extension key and zensical_code_references import path.
  • Importing zensical_code_references emits a DeprecationWarning.

What this gives you

Markdown usage stays standard:

--8<-- "my_pkg.api:Client.send"

You reference symbols instead of brittle line ranges, so snippets stay correct when code moves.

Backward compatibility

Existing pymdownx.snippets syntax continues to work unchanged. Symbolic resolution is only applied when the target matches a real Python module under module_roots.

--8<-- "docs/intro.md"
--8<-- "docs/intro.md:intro"
--8<-- "src/my_pkg/api.py:12:20"
--8<-- "my_pkg.api:Client.send"

Install

uv add pymdown-symbolic-snippets

Or:

pip install pymdown-symbolic-snippets

zensical is optional. This package works as a Python-Markdown extension without zensical; install zensical only if you want to run Zensical builds.

Why this exists

Raw line ranges are brittle. If code moves, references like file.py:88:121 rot.

This extension allows snippet references by Python symbol and resolves them to real line spans at build time using AST.

Symbol reference format

<module.path>:<symbol>(.<nested>)[:start[:end]]

Examples:

  • my_pkg.api:build_payload
  • my_pkg.api:Client.send
  • my_pkg.config:DEFAULT_TIMEOUT:-1:2

Resolved output is rewritten to standard snippets format:

path/to/file.py:start:end

For method references without selectors, output uses a multi-range selector so the class header and method body are included together:

path/to/file.py:class_header_start:class_header_end,method_start:method_end

Selector behavior

  • If you don't add a selector, the whole symbol is used.
  • For method references with no selector, the selection includes the class declaration line(s) and that method's body, but not other methods in the class (for example, not __init__).
  • :start means "start at this line (relative to the symbol) and go to the end of the symbol."
  • :start:end means "use only this relative line range inside the symbol."
  • Positive numbers are 1-based: 1 is the first line of the symbol.
  • 0 and negative numbers are offsets: 0 is the symbol start, -1 is one line above the symbol start.
  • If start or end goes past the file limits, values are clamped to valid file bounds.
  • If the range is invalid (end < start), resolution fails.

Ecosystem comparison

Research summary across pymdown-extensions, mkdocs, mkdocs-material, and common include plugins:

Tool / project Symbol path include (module:Class.method) AST/introspection-based resolution Generic snippet include Equivalent to this project
pymdownx.snippets No No Yes (file, line ranges, named marker sections) No
mkdocs No No Not in core (delegates to extensions/plugins) No
mkdocs-material No No Yes via upstream pymdownx.snippets No
mkdocstrings/python Partial (API object rendering) Yes (object collection) No (not a general snippets include engine) Partial
mkdocs-codeinclude-plugin No No Yes (token/brace-targeted blocks) No
mkdocs-include-markdown-plugin No No Yes (delimiter-based includes) No
pymdown-symbolic-snippets (this project) Yes Yes Yes (rewrites to pymdownx.snippets line spans) Yes

Bottom line: existing options either slice by lines/markers or render API docs; none provide first-class symbol-addressed snippet transclusion in the same workflow as pymdownx.snippets.

Python-Markdown configuration

Use it as a normal Python-Markdown extension, placed before pymdownx.snippets:

import markdown

md = markdown.Markdown(
    extensions=[
        "pymdown_symbolic_snippets",
        "pymdownx.snippets",
    ],
    extension_configs={
        "pymdown_symbolic_snippets": {
            "module_roots": ["src"],
            "fail_on_unresolved": True,
        },
        "pymdownx.snippets": {
            "base_path": ["src"],
            "check_paths": True,
        },
    },
)

Zensical configuration (site.toml)

[project.markdown_extensions.pymdown_symbolic_snippets]
module_roots = ["src"]
fail_on_unresolved = true

[project.markdown_extensions.pymdownx.highlight]
anchor_linenums = true
line_spans = "__span"
pygments_lang_class = true

[project.markdown_extensions.pymdownx.snippets]
base_path = ["src"]
check_paths = true

[project.markdown_extensions.pymdownx.superfences]

If you define project.markdown_extensions explicitly, include all extensions you rely on. Leaving out pymdownx.superfences/pymdownx.highlight causes fenced blocks to render as plain text.

Included proof project

This repo includes a working Zensical example that references this package's own source to prove behavior:

  • Config: examples/symbolic-snippets/site.toml
  • Docs page: examples/symbolic-snippets/docs/index.md

Build it:

uv run zensical build --config-file examples/symbolic-snippets/site.toml

Tiny output example (from examples/symbolic-snippets/site/index.html):

def parse_symbolic_reference(value: str) -> SymbolicReference | None:
    if ":" not in value:
        return None

Tests

Run:

uv run pytest

The suite includes parser/resolver tests plus an E2E Zensical build test that asserts resolved symbols are rendered in generated HTML.

Release automation

GitHub Actions is configured to publish to PyPI on strict semver tags:

  • CI workflow: .github/workflows/ci.yml
  • Release workflow: .github/workflows/release.yml
  • Trigger: push tag matching vX.Y.Z
  • Guardrails: tag must be strict semver and must match project.version in pyproject.toml
  • Gate: test matrix (3.13, 3.14) must pass before publish

One-time GitHub setup for trusted publishing:

  1. Create environment pypi in repository settings.
  2. Configure PyPI Trusted Publisher for this repository/workflow.

Release command:

git tag v0.1.0
git push upstream v0.1.0

Metadata

Release files for pymdown-symbolic-snippets 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pymdown-symbolic-snippets 0.1.0
File Size Uploaded
pymdown_symbolic_snippets-0.1.0.tar.gz 7.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pymdown-symbolic-snippets 0.1.0
File Interpreter ABI Platform
pymdown_symbolic_snippets-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 17.2 kB

Release files / pymdown_symbolic_snippets-0.1.0.tar.gz

Download URL pymdown_symbolic_snippets-0.1.0.tar.gz
Size 7.8 kB
Tags Source
SHA-256 checksum
How to use checksums
4079a389cbfd484dfe9a4bc082f8ca6c58af01e055421811e72b43cd4d86e631
BLAKE2b-256 checksum
How to use checksums
93c3cb3b7787d3c80edac5c344799acdb999ced4f6243dce80d9455532f410e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pymdown_symbolic_snippets-0.1.0-py3-none-any.whl

Download URL pymdown_symbolic_snippets-0.1.0-py3-none-any.whl
Size 9.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f1a452e4b56174fd004f3c9ef89ff554cb0e1e6969ceb85eb1b3e6b9d8213841
BLAKE2b-256 checksum
How to use checksums
802101d82f08886f5c23201e8299ed3d9033893d8c234e14132efca5370bc60d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page