mirror of
https://github.com/vinta/awesome-python.git
synced 2026-05-07 08:20:21 -05:00
add missing links of category descriptions
This commit is contained in:
@@ -27,6 +27,7 @@ class ParsedSection(TypedDict):
|
||||
name: str
|
||||
slug: str
|
||||
description: str # plain text, links resolved to text
|
||||
description_html: str # inline HTML, properly escaped
|
||||
entries: list[ParsedEntry]
|
||||
entry_count: int
|
||||
|
||||
@@ -113,22 +114,22 @@ def _heading_text(node: SyntaxTreeNode) -> str:
|
||||
return ""
|
||||
|
||||
|
||||
def _extract_description(nodes: list[SyntaxTreeNode]) -> str:
|
||||
"""Extract description from the first paragraph if it's a single <em> block.
|
||||
def _extract_description_children(nodes: list[SyntaxTreeNode]) -> list[SyntaxTreeNode]:
|
||||
"""Extract description children from the first paragraph if it's a single <em> block.
|
||||
|
||||
Pattern: _Libraries for foo._ -> "Libraries for foo."
|
||||
"""
|
||||
if not nodes:
|
||||
return ""
|
||||
return []
|
||||
first = nodes[0]
|
||||
if first.type != "paragraph":
|
||||
return ""
|
||||
return []
|
||||
for child in first.children:
|
||||
if child.type == "inline" and len(child.children) == 1:
|
||||
em = child.children[0]
|
||||
if em.type == "em":
|
||||
return render_inline_text(em.children)
|
||||
return ""
|
||||
return em.children
|
||||
return []
|
||||
|
||||
|
||||
# --- Entry extraction --------------------------------------------------------
|
||||
@@ -258,14 +259,17 @@ def _parse_section_entries(content_nodes: list[SyntaxTreeNode]) -> list[ParsedEn
|
||||
|
||||
def _build_section(name: str, body: list[SyntaxTreeNode]) -> ParsedSection:
|
||||
"""Build a ParsedSection from a heading name and its body nodes."""
|
||||
desc = _extract_description(body)
|
||||
content_nodes = body[1:] if desc else body
|
||||
desc_children = _extract_description_children(body)
|
||||
desc = render_inline_text(desc_children) if desc_children else ""
|
||||
desc_html = render_inline_html(desc_children) if desc_children else ""
|
||||
content_nodes = body[1:] if desc_children else body
|
||||
entries = _parse_section_entries(content_nodes)
|
||||
entry_count = len(entries) + sum(len(e["also_see"]) for e in entries)
|
||||
return ParsedSection(
|
||||
name=name,
|
||||
slug=slugify(name),
|
||||
description=desc,
|
||||
description_html=desc_html,
|
||||
entries=entries,
|
||||
entry_count=entry_count,
|
||||
)
|
||||
|
||||
@@ -423,6 +423,17 @@ kbd {
|
||||
text-wrap: pretty;
|
||||
}
|
||||
|
||||
.category-subtitle a {
|
||||
color: var(--hero-text);
|
||||
text-decoration: underline;
|
||||
text-decoration-color: oklch(100% 0 0 / 0.32);
|
||||
text-underline-offset: 0.2em;
|
||||
}
|
||||
|
||||
.category-subtitle a:hover {
|
||||
text-decoration-color: oklch(100% 0 0 / 0.7);
|
||||
}
|
||||
|
||||
.category-results {
|
||||
padding-top: clamp(2.5rem, 5vw, 3.75rem);
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
<div class="category-hero-copy">
|
||||
<h1>{{ category.name }}</h1>
|
||||
{% if category.description %}
|
||||
<p class="category-subtitle">{{ category.description }}</p>
|
||||
{% if category.description_html %}
|
||||
<p class="category-subtitle">{{ category.description_html | safe }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -146,7 +146,7 @@ class TestBuild:
|
||||
|
||||
## Widgets
|
||||
|
||||
_Widget libraries._
|
||||
_Widget libraries. Also see [awesome-widgets](https://example.com/widgets)._
|
||||
|
||||
- [w1](https://example.com) - A widget.
|
||||
|
||||
@@ -235,7 +235,7 @@ class TestBuild:
|
||||
|
||||
## Widgets
|
||||
|
||||
_Widget libraries._
|
||||
_Widget libraries. Also see [awesome-widgets](https://example.com/widgets)._
|
||||
|
||||
- [w1](https://example.com/w1) - A widget.
|
||||
- [w2](https://github.com/owner/w2) - A starred widget.
|
||||
@@ -276,12 +276,12 @@ class TestBuild:
|
||||
assert 'href="/categories/widgets/"' in index_html
|
||||
assert 'data-value="Widgets"' in index_html
|
||||
assert parser.title.strip() == "Widgets Python Libraries | Awesome Python"
|
||||
assert parser.meta_by_name["description"] == "Explore 2 curated Python projects in Widgets. Widget libraries."
|
||||
assert parser.meta_by_name["description"] == "Explore 2 curated Python projects in Widgets. Widget libraries. Also see awesome-widgets."
|
||||
assert parser.links_by_rel["canonical"] == "https://awesome-python.com/categories/widgets/"
|
||||
assert parser.meta_by_property["og:url"] == "https://awesome-python.com/categories/widgets/"
|
||||
assert '<link rel="alternate" type="text/markdown" href="/index.md" />' not in category_html
|
||||
assert "<h1>Widgets</h1>" in category_html
|
||||
assert "Widget libraries." in category_html
|
||||
assert 'Widget libraries. Also see <a href="https://example.com/widgets" target="_blank" rel="noopener">awesome-widgets</a>.' in category_html
|
||||
assert 'href="https://example.com/w1"' in category_html
|
||||
assert "A widget." in category_html
|
||||
assert 'href="https://github.com/owner/w2"' in category_html
|
||||
|
||||
@@ -180,7 +180,9 @@ class TestParseReadmeSections:
|
||||
groups = parse_readme(MINIMAL_README)
|
||||
cats = groups[0]["categories"]
|
||||
assert cats[0]["description"] == "Libraries for alpha stuff."
|
||||
assert cats[0]["description_html"] == "Libraries for alpha stuff."
|
||||
assert cats[1]["description"] == "Tools for beta."
|
||||
assert cats[1]["description_html"] == "Tools for beta."
|
||||
|
||||
def test_contributing_skipped(self):
|
||||
groups = parse_readme(MINIMAL_README)
|
||||
@@ -216,6 +218,7 @@ class TestParseReadmeSections:
|
||||
groups = parse_readme(readme)
|
||||
cats = groups[0]["categories"]
|
||||
assert cats[0]["description"] == ""
|
||||
assert cats[0]["description_html"] == ""
|
||||
assert cats[0]["entries"][0]["name"] == "item"
|
||||
|
||||
def test_description_with_link_stripped(self):
|
||||
@@ -237,6 +240,7 @@ class TestParseReadmeSections:
|
||||
groups = parse_readme(readme)
|
||||
cats = groups[0]["categories"]
|
||||
assert cats[0]["description"] == "Algorithms. Also see awesome-algos."
|
||||
assert cats[0]["description_html"] == 'Algorithms. Also see <a href="https://example.com" target="_blank" rel="noopener">awesome-algos</a>.'
|
||||
|
||||
|
||||
class TestParseGroupedReadme:
|
||||
@@ -481,6 +485,7 @@ class TestParseRealReadme:
|
||||
algos = next(c for c in self.cats if c["name"] == "Algorithms and Design Patterns")
|
||||
assert "awesome-algorithms" in algos["description"]
|
||||
assert "https://" not in algos["description"]
|
||||
assert 'href="https://github.com/tayllan/awesome-algorithms"' in algos["description_html"]
|
||||
|
||||
def test_miscellaneous_in_own_group(self):
|
||||
misc_group = next((g for g in self.groups if g["name"] == "Miscellaneous"), None)
|
||||
|
||||
Reference in New Issue
Block a user