repomatic.site_anchors module¶
Same-page fragment links, checked against the anchors the build produced.
A literal ](#fragment) is the one cross-reference nothing resolves. A
:ref: or :doc: role goes through Sphinx, which reports a missing target
under nitpicky; a raw fragment is copied into the HTML untouched, so a slug
that never existed ships as a link that looks fine and lands nowhere. The
build stays green because it was never asked a question.
Caution
A Markdown link checker cannot stand in for this, because it has to guess the
slug. Measured against lychee 0.24.2 on the heading ## The pages.dev
hostname`: myst-parser builds``the-pages-dev-hostname`, lychee’s GitHub-style
slugger wants the-pagesdev-hostname, and each reports the other as broken.
That disagreement is why this repository excludes intra-docs fragments from
lychee altogether, which left the class with no coverage at all until a
#the-pagesdev-hostname link shipped against a the-pages-dev-hostname
anchor.
The built page is the only authority, so that is what this reads. Fragments come from the Markdown source rather than from the rendered HTML, which is what keeps the check to what an author actually wrote: a theme’s own footnote backrefs and header permalinks never enter, so there is no denylist to keep.
- repomatic.site_anchors.ANCHOR_ATTRIBUTES = frozenset({'id', 'name'})¶
HTML attributes a browser will scroll a fragment to.
- repomatic.site_anchors.DEFAULT_BUILD_DIR = PosixPath('docs/_build')¶
Where the Sphinx builders in this project’s workflows write the site.
- repomatic.site_anchors.DEFAULT_DOCS_DIR = PosixPath('docs')¶
Conventional root of a Sphinx source tree.
- repomatic.site_anchors.FENCE_RE = re.compile('^\\s*(?:`{3,}|~{3,})')¶
Opening or closing line of a fenced code block.
- repomatic.site_anchors.FRAGMENT_LINK_RE = re.compile(']\\(#(?P<fragment>[^)\\s]+)')¶
An authored same-page link,
](#fragment).Anchored on the
](#sequence, which is what makes it same-page: a link to another document carries a path before its#and is Sphinx’s problem, not this one.
- repomatic.site_anchors.INLINE_CODE_RE = re.compile('(?P<ticks>`+)(?:.|\\n)*?(?P=ticks)')¶
An inline code span, of any backtick width.
- repomatic.site_anchors.MARKDOWN_SUFFIX = '.md'¶
Extension of the sources scanned for authored links.
- class repomatic.site_anchors.MissingAnchor(source, fragment, page)[source]¶
Bases:
objectOne authored fragment with no anchor to land on.
- class repomatic.site_anchors.AnchorReport(missing=<factory>, unbuilt=<factory>, checked=0)[source]¶
Bases:
objectWhat one sweep over a docs tree found.
- missing: list[MissingAnchor]¶
Every authored fragment that resolves to nothing.
- unbuilt: list[Path]¶
Sources with no built page, so with nothing to check against.
A page left out of every toctree, or a fragment file meant only to be included by another, lands here. Reported rather than failed: the build is what decides which sources become pages, and it is not this check’s place to second-guess it.
- repomatic.site_anchors.strip_code(text)[source]¶
Blank out every code span and fenced block of a Markdown source.
A fence showing
](#example)documents a link rather than making one, and checking it would fail a page for its own example. Lines are replaced rather than deleted so a reported line number still points at the source.
- repomatic.site_anchors.authored_fragments(text)[source]¶
Every same-page fragment a Markdown source links to.
- repomatic.site_anchors.built_page(source, docs_dir, build_dir)[source]¶
Locate the page a Markdown source was rendered into.
Both Sphinx HTML builders are covered by trying each layout in turn:
htmlwrites{name}.html,dirhtmlwrites{name}/index.html. Probing rather than reading[tool.repomatic] sphinx.builderkeeps the check honest about the tree in front of it, and correct for a caller pointed at a directory some other builder wrote.
- repomatic.site_anchors.markdown_sources(docs_dir, build_dir)[source]¶
Every authored Markdown source under a docs tree.
Skips the rendered site, which commonly sits inside the source tree, and every underscore-prefixed directory, Sphinx’s own convention for the static and template folders that hold no authored prose.