posit-dev / posit-dev/great-docs
`_fix_numeric_prefix_links` only rewrites `.qmd` links, but section discovery strips numeric prefixes from `.md` files too
@has2k1 is already working on this.
Since Sep 17, 2026.
- Dominant language
- Python
- Stars
- 262
- Forks
- 18
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 14
Description
Summary
Section discovery accepts both .qmd and .md, and _copy_section_files strips numeric ordering prefixes from the filenames of both. But _fix_numeric_prefix_links — which exists to keep cross-references working across that rename — matches .qmd only.
So a .md page is renamed on copy and every link to it keeps the old, prefixed name. The file lands at specs/security.html; the link still points at 00-security.md.
Sibling of #215, which was the directory half of the same rewrite and is fixed. This is the extension half.
Root cause
core.py, _fix_numeric_prefix_links:
return re.sub(r"\]\((?!https?://|/)([^)]+\.qmd(?:[#?][^)]*)?)\)", _rewrite, content)
while section discovery (core.py ~L3012) accepts both:
if f.suffix in (".qmd", ".md") and f.name != "README.md"
and the copy step renames both — clean_name = self._strip_numeric_prefix(rel.name) — with the title derivation right below it explicitly handling both extensions:
title = clean_name.replace(".qmd", "").replace(".md", "").replace("-", " ").title()
Reproducing the regex directly
import re
RX = re.compile(r'\]\((?!https?://|/)([^)]+\.qmd(?:[#?][^)]*)?)\)')
# ... same _rewrite as core.py
'[Security](00-security.qmd)' -> '[Security](security.qmd)' # rewritten
'[Security](00-security.md)' -> '[Security](00-security.md)' # NOT rewritten
'[Auth](../specs/01-auth.qmd#grants)' -> '[Auth](../specs/auth.qmd#grants)'
'[Auth](../specs/01-auth.md#grants)' -> '[Auth](../specs/01-auth.md#grants)'
Minimal repro
# great-docs.yml
sections:
- title: Specs
dir: docs/specs
index: true
docs/specs/
00-security.md # contains: [Auth](01-auth.md)
01-auth.md
great-docs build → docs/specs/00-security.md is published as security.html, 01-auth.md as auth.html, and the link in the built page still points at 01-auth.md, which does not exist. Renaming both sources to .qmd fixes it.
Suggested fix
Widen the extension group:
r"\]\((?!https?://|/)([^)]+\.(?:qmd|md)(?:[#?][^)]*)?)\)"
Impact
Any docs-heavy project whose sources are Markdown rather than Quarto and that uses numeric prefixes for ordering. In our repo it is 58 links across 12 spec files, which we currently repair ourselves by post-processing the built HTML.
Version
great-docs 0.17.0 (latest on PyPI at time of writing), Python 3.13, Windows.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.