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.
Summary
Section discovery accepts both
.qmdand.md, and_copy_section_filesstrips numeric ordering prefixes from the filenames of both. But_fix_numeric_prefix_links— which exists to keep cross-references working across that rename — matches.qmdonly.So a
.mdpage is renamed on copy and every link to it keeps the old, prefixed name. The file lands atspecs/security.html; the link still points at00-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:while section discovery (
core.py~L3012) accepts both: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:Reproducing the regex directly
Minimal repro
great-docs build→docs/specs/00-security.mdis published assecurity.html,01-auth.mdasauth.html, and the link in the built page still points at01-auth.md, which does not exist. Renaming both sources to.qmdfixes 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-docs0.17.0 (latest on PyPI at time of writing), Python 3.13, Windows.