posit-dev / posit-dev/great-docs

`_fix_numeric_prefix_links` only rewrites `.qmd` links, but section discovery strips numeric prefixes from `.md` files too

Open
#349 1 comment 0 reactions 1 assignee View on GitHub

@has2k1 is already working on this.

Since Sep 17, 2026.

Difficulty: [2] Intermediate Effort: [2] Medium Priority: [3] High Type: ☹︎ Bug
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 builddocs/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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.