fix: link full project names in intro picks that matched only part

Nine picks, such as "OpenAI Agents SDK", "MCP Python SDK", and "Jupyter Notebook", linked only part of the name or nothing, because the README lists those projects under their PyPI or repo names. The punctuation-guard test used "The Algorithms - Python", which now matches its alias in full, so it uses a made-up name instead.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Vinta Chen
2026-10-21 22:44:16 +08:00
co-authored by Claude
parent af95036e0e
commit 9177a2e8a7
2 changed files with 13 additions and 4 deletions
+10 -1
View File
@@ -47,23 +47,32 @@ PICK_ALIASES = {
"Cacheops": "django-cacheops",
"Chroma": "chromadb",
"Coverage.py": "coverage",
"Django AI Skills": "django-ai-plugins",
"Django ORM": "django.db.models",
"Faiss": "faiss-cpu",
"gRPC": "grpcio",
"Google Cloud client libraries": "google-cloud-python",
"Grappelli": "django-grappelli",
"Hydra": "hydra-core",
"Ibis": "ibis-framework",
"Jupyter Notebook": "notebook",
"Material for MkDocs": "mkdocs-material",
"MCP Python SDK": "mcp",
"Odoo Community": "odoo",
"Odoo Enterprise": "odoo",
"Odoo Online": "odoo",
"OpenAI Agents SDK": "openai-agents",
"OpenCV": "opencv-python",
"Playwright": "playwright-python",
"PyAV": "av",
"Python-Markdown": "markdown",
"python-oracledb": "oracledb",
"Ray Core": "ray",
"redis-py": "redis",
"Sherlock": "sherlock-project",
"Silk": "django-silk",
"Surprise": "scikit-surprise",
"The Algorithms - Python": "thealgorithms",
"Unfold": "django-unfold",
"Vega-Altair": "altair",
}
@@ -309,7 +318,7 @@ def link_pick_names(pick: str, slugs_by_key: dict[str, str]) -> str:
start, end = words[i].start(), words[j - 1].end()
span = pick[start:end]
slug = slugs_by_key.get(entry_name_key(span))
# Code spans and dangling punctuation like "The Algorithms -" stay outside links
# Code spans and dangling punctuation like "Django -" stay outside links
if slug and span[0].isalnum() and span[-1].isalnum() and "," not in span and "`" not in span:
parts.append(f"{pick[pos:start]}[{span}](#entry-{slug})")
pos, i = end, j
+3 -3
View File
@@ -1686,12 +1686,12 @@ class TestLoadCategoryIntro:
def test_links_picks_to_entry_rows(self, tmp_path):
path = tmp_path / "widgets.md"
path.write_text(
"Use w1.\n\nHow to choose:\n\n- Small apps: Django Ninja, or `uv tool` on uv\n- Big apps: Django\n- Old apps: The Algorithms - Python\n\nSee [w1](https://w1.example).\n", encoding="utf-8"
"Use w1.\n\nHow to choose:\n\n- Small apps: Django Ninja, or `uv tool` on uv\n- Big apps: Django\n- Old apps: Django - LTS releases\n\nSee [w1](https://w1.example).\n", encoding="utf-8"
)
intro_html, guide_html, _, _ = load_category_intro(path, ["django-ninja", "Django", "uv", "TheAlgorithms"])
intro_html, guide_html, _, _ = load_category_intro(path, ["django-ninja", "Django", "uv"])
assert '<li>Small apps: <a href="#entry-django-ninja">Django Ninja</a>, or <code>uv tool</code> on <a href="#entry-uv">uv</a></li>' in intro_html
assert '<li>Big apps: <a href="#entry-django">Django</a></li>' in intro_html
assert '<li>Old apps: <a href="#entry-thealgorithms">The Algorithms</a> - Python</li>' in intro_html
assert '<li>Old apps: <a href="#entry-django">Django</a> - LTS releases</li>' in intro_html
assert '<a href="https://w1.example" target="_blank" rel="noopener">w1</a>' in guide_html
def test_links_pick_aliases_to_entry_rows(self, tmp_path):