musaw commited on
Commit ·
3614ee2
1
Parent(s): 204c5d9
fix(ui): prevent card overflow and improve task labeling for v1.1.1
Browse files- CHANGELOG.md +10 -0
- CITATION.cff +2 -1
- README.md +2 -1
- docs/index.md +2 -1
- docs/releases/README.md +3 -1
- docs/releases/v1.1.1.md +33 -0
- docs/search/index.html +157 -33
- pyproject.toml +2 -1
CHANGELOG.md
CHANGED
|
@@ -20,6 +20,16 @@ and this project uses semantic version tags with a fixed role per figure:
|
|
| 20 |
### Fixed
|
| 21 |
- None yet.
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
## [v1.0.1] - 2026-02-18
|
| 24 |
### Added
|
| 25 |
- Promoted 6 high-confidence, non-duplicate Hugging Face resources to verified catalog:
|
|
|
|
| 20 |
### Fixed
|
| 21 |
- None yet.
|
| 22 |
|
| 23 |
+
## [v1.1.1] - 2026-02-18
|
| 24 |
+
### Changed
|
| 25 |
+
- Improved search-page readability and usability in `docs/search/index.html`.
|
| 26 |
+
- Expanded short task labels into clearer full-form labels in UI controls and resource cards.
|
| 27 |
+
- Standardized title casing for key UI labels and actions.
|
| 28 |
+
|
| 29 |
+
### Fixed
|
| 30 |
+
- Prevented long resource titles and long unbroken strings from overflowing card boundaries.
|
| 31 |
+
- Improved capitalization and display formatting for source and task text in search results.
|
| 32 |
+
|
| 33 |
## [v1.0.1] - 2026-02-18
|
| 34 |
### Added
|
| 35 |
- Promoted 6 high-confidence, non-duplicate Hugging Face resources to verified catalog:
|
CITATION.cff
CHANGED
|
@@ -2,7 +2,7 @@ cff-version: 1.2.0
|
|
| 2 |
message: "If you use this repository, please cite it."
|
| 3 |
title: "Pashto Language Resources Hub (Pukhto/Pashto)"
|
| 4 |
type: software
|
| 5 |
-
version: 1.
|
| 6 |
date-released: 2026-02-18
|
| 7 |
license: Apache-2.0
|
| 8 |
repository-code: "https://github.com/Musawer1214/pashto-language-resources"
|
|
@@ -20,3 +20,4 @@ keywords:
|
|
| 20 |
- machine translation
|
| 21 |
- language resources
|
| 22 |
|
|
|
|
|
|
| 2 |
message: "If you use this repository, please cite it."
|
| 3 |
title: "Pashto Language Resources Hub (Pukhto/Pashto)"
|
| 4 |
type: software
|
| 5 |
+
version: 1.1.1
|
| 6 |
date-released: 2026-02-18
|
| 7 |
license: Apache-2.0
|
| 8 |
repository-code: "https://github.com/Musawer1214/pashto-language-resources"
|
|
|
|
| 20 |
- machine translation
|
| 21 |
- language resources
|
| 22 |
|
| 23 |
+
|
README.md
CHANGED
|
@@ -73,7 +73,7 @@ python -m pytest -q
|
|
| 73 |
## Releases
|
| 74 |
|
| 75 |
- Release notes index: [docs/releases/README.md](docs/releases/README.md)
|
| 76 |
-
- Latest release notes: [v1.
|
| 77 |
- Changelog: [CHANGELOG.md](CHANGELOG.md)
|
| 78 |
|
| 79 |
## Contributing
|
|
@@ -82,3 +82,4 @@ python -m pytest -q
|
|
| 82 |
- Community communication: [community/COMMUNICATION.md](community/COMMUNICATION.md)
|
| 83 |
- Resource guidelines: [docs/dataset_guidelines.md](docs/dataset_guidelines.md)
|
| 84 |
|
|
|
|
|
|
| 73 |
## Releases
|
| 74 |
|
| 75 |
- Release notes index: [docs/releases/README.md](docs/releases/README.md)
|
| 76 |
+
- Latest release notes: [v1.1.1](docs/releases/v1.1.1.md)
|
| 77 |
- Changelog: [CHANGELOG.md](CHANGELOG.md)
|
| 78 |
|
| 79 |
## Contributing
|
|
|
|
| 82 |
- Community communication: [community/COMMUNICATION.md](community/COMMUNICATION.md)
|
| 83 |
- Resource guidelines: [docs/dataset_guidelines.md](docs/dataset_guidelines.md)
|
| 84 |
|
| 85 |
+
|
docs/index.md
CHANGED
|
@@ -43,7 +43,7 @@ description: Open-source Pashto (Pukhto/Pashto) datasets, models, benchmarks, AS
|
|
| 43 |
## Releases
|
| 44 |
|
| 45 |
- Release notes index: [releases/README.md](releases/README.md)
|
| 46 |
-
- Current release notes: [v1.
|
| 47 |
- Changelog: [../CHANGELOG.md](../CHANGELOG.md)
|
| 48 |
|
| 49 |
## Contribution
|
|
@@ -58,3 +58,4 @@ Start here:
|
|
| 58 |
|
| 59 |
This project is released under Apache 2.0. See [LICENSE](../LICENSE).
|
| 60 |
|
|
|
|
|
|
| 43 |
## Releases
|
| 44 |
|
| 45 |
- Release notes index: [releases/README.md](releases/README.md)
|
| 46 |
+
- Current release notes: [v1.1.1](releases/v1.1.1.md)
|
| 47 |
- Changelog: [../CHANGELOG.md](../CHANGELOG.md)
|
| 48 |
|
| 49 |
## Contribution
|
|
|
|
| 58 |
|
| 59 |
This project is released under Apache 2.0. See [LICENSE](../LICENSE).
|
| 60 |
|
| 61 |
+
|
docs/releases/README.md
CHANGED
|
@@ -4,13 +4,15 @@ This directory stores versioned release notes for the project.
|
|
| 4 |
|
| 5 |
## Current
|
| 6 |
|
| 7 |
-
- [v1.
|
| 8 |
|
| 9 |
## Previous
|
| 10 |
|
|
|
|
| 11 |
- [v1.0.0](v1.0.0.md)
|
| 12 |
|
| 13 |
## Notes
|
| 14 |
|
|
|
|
| 15 |
- `v1.0.1` is a resource-catalog release (third figure update).
|
| 16 |
- Earlier bootstrap history (`v0.1`) remains documented in [../../CHANGELOG.md](../../CHANGELOG.md).
|
|
|
|
| 4 |
|
| 5 |
## Current
|
| 6 |
|
| 7 |
+
- [v1.1.1](v1.1.1.md)
|
| 8 |
|
| 9 |
## Previous
|
| 10 |
|
| 11 |
+
- [v1.0.1](v1.0.1.md)
|
| 12 |
- [v1.0.0](v1.0.0.md)
|
| 13 |
|
| 14 |
## Notes
|
| 15 |
|
| 16 |
+
- `v1.1.1` is a code-fix release (middle figure update).
|
| 17 |
- `v1.0.1` is a resource-catalog release (third figure update).
|
| 18 |
- Earlier bootstrap history (`v0.1`) remains documented in [../../CHANGELOG.md](../../CHANGELOG.md).
|
docs/releases/v1.1.1.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Release Notes: v1.1.1
|
| 2 |
+
|
| 3 |
+
Release date: 2026-02-18
|
| 4 |
+
Tag: `v1.1.1`
|
| 5 |
+
|
| 6 |
+
## Summary
|
| 7 |
+
|
| 8 |
+
Code-fix release focused on search-page UI correctness, readability, and terminology clarity.
|
| 9 |
+
|
| 10 |
+
## Highlights
|
| 11 |
+
|
| 12 |
+
- Fixed long-text overflow so content remains inside resource cards.
|
| 13 |
+
- Improved task labels to use clear full forms where needed.
|
| 14 |
+
- Applied better capitalization across key search UI labels.
|
| 15 |
+
- Improved rendering consistency for long titles and source text.
|
| 16 |
+
|
| 17 |
+
## Validation
|
| 18 |
+
|
| 19 |
+
- `python scripts/check_links.py`
|
| 20 |
+
- `python scripts/validate_resource_catalog.py`
|
| 21 |
+
- `python scripts/validate_normalization.py data/processed/normalization_seed_v0.1.tsv`
|
| 22 |
+
- `python -m pytest -q`
|
| 23 |
+
|
| 24 |
+
## Versioning Rule Applied
|
| 25 |
+
|
| 26 |
+
This release follows the project rule:
|
| 27 |
+
|
| 28 |
+
- `vMAJOR.CODE.RESOURCE`
|
| 29 |
+
- Code-fix updates increment the middle figure.
|
| 30 |
+
|
| 31 |
+
## Compare
|
| 32 |
+
|
| 33 |
+
- [GitHub compare: v1.0.1...v1.1.1](https://github.com/Musawer1214/pashto-language-resources/compare/v1.0.1...v1.1.1)
|
docs/search/index.html
CHANGED
|
@@ -10,7 +10,7 @@ permalink: /search/
|
|
| 10 |
<meta charset="utf-8">
|
| 11 |
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 12 |
<title>Pashto Resource Search</title>
|
| 13 |
-
<meta name="description" content="Search verified Pashto (Pukhto/Pashto) resources for ASR, TTS, NLP, machine translation, tools, datasets, models, and benchmarks.">
|
| 14 |
<meta name="keywords" content="Pashto resources, Pukhto resources, Pashto datasets, Pashto ASR, Pashto TTS, Pashto NLP, Pashto machine translation, Pashto benchmarks">
|
| 15 |
<meta name="robots" content="index,follow,max-image-preview:large">
|
| 16 |
<link rel="canonical" href="https://musawer1214.github.io/pashto-language-resources/search/">
|
|
@@ -28,7 +28,7 @@ permalink: /search/
|
|
| 28 |
"@type": "CollectionPage",
|
| 29 |
"name": "Pashto Resource Search",
|
| 30 |
"url": "https://musawer1214.github.io/pashto-language-resources/search/",
|
| 31 |
-
"description": "Search verified and candidate Pashto resources for ASR, TTS, NLP,
|
| 32 |
"inLanguage": "en",
|
| 33 |
"about": [
|
| 34 |
"Pashto datasets",
|
|
@@ -354,12 +354,18 @@ permalink: /search/
|
|
| 354 |
margin: 0;
|
| 355 |
font-size: 17px;
|
| 356 |
line-height: 1.3;
|
|
|
|
|
|
|
| 357 |
}
|
| 358 |
|
| 359 |
.title a {
|
| 360 |
color: var(--ink);
|
| 361 |
text-decoration: none;
|
| 362 |
border-bottom: 1px solid transparent;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 363 |
}
|
| 364 |
|
| 365 |
.title a:hover { border-bottom-color: currentColor; }
|
|
@@ -369,6 +375,8 @@ permalink: /search/
|
|
| 369 |
color: var(--muted);
|
| 370 |
line-height: 1.48;
|
| 371 |
font-size: 13px;
|
|
|
|
|
|
|
| 372 |
}
|
| 373 |
|
| 374 |
.meta-links {
|
|
@@ -384,12 +392,18 @@ permalink: /search/
|
|
| 384 |
font-weight: 700;
|
| 385 |
color: var(--brand);
|
| 386 |
text-decoration: none;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 387 |
}
|
| 388 |
|
| 389 |
.tasks {
|
| 390 |
font-size: 12px;
|
| 391 |
color: var(--muted);
|
| 392 |
margin: 0;
|
|
|
|
|
|
|
| 393 |
}
|
| 394 |
|
| 395 |
.empty {
|
|
@@ -446,7 +460,7 @@ permalink: /search/
|
|
| 446 |
<p class="eyebrow">Pukhto / Pashto Resources</p>
|
| 447 |
<h1>Pashto Technology Resource Search</h1>
|
| 448 |
<p class="subtitle">
|
| 449 |
-
Filter verified and candidate resources for ASR, TTS, NLP, translation, tools, and benchmark work.
|
| 450 |
Share search states with URL parameters and jump quickly to high-intent pages.
|
| 451 |
</p>
|
| 452 |
</div>
|
|
@@ -458,9 +472,9 @@ permalink: /search/
|
|
| 458 |
</div>
|
| 459 |
<nav class="quick-links" aria-label="Quick links">
|
| 460 |
<a class="pill-link" href="../">Docs Home</a>
|
| 461 |
-
<a class="pill-link" href="../pashto_datasets.
|
| 462 |
-
<a class="pill-link" href="../pashto_asr.
|
| 463 |
-
<a class="pill-link" href="../pashto_tts.
|
| 464 |
<a class="pill-link" href="https://github.com/Musawer1214/pashto-language-resources">GitHub</a>
|
| 465 |
<a class="pill-link" href="https://huggingface.co/Musawer14/pashto-language-resources">Hugging Face</a>
|
| 466 |
</nav>
|
|
@@ -470,7 +484,7 @@ permalink: /search/
|
|
| 470 |
<div class="controls">
|
| 471 |
<div class="field search">
|
| 472 |
<label for="q">Search</label>
|
| 473 |
-
<input id="q" type="search" placeholder="Try:
|
| 474 |
</div>
|
| 475 |
<div class="field">
|
| 476 |
<label for="category">Category</label>
|
|
@@ -501,12 +515,12 @@ permalink: /search/
|
|
| 501 |
|
| 502 |
<div class="action-row">
|
| 503 |
<div class="group" role="group" aria-label="Result view mode">
|
| 504 |
-
<button type="button" class="btn active" id="viewGrid">Grid
|
| 505 |
-
<button type="button" class="btn" id="viewList">List
|
| 506 |
</div>
|
| 507 |
<div class="group">
|
| 508 |
-
<button type="button" class="btn light" id="clearFilters">Clear
|
| 509 |
-
<button type="button" class="btn brand" id="copyLink">Copy
|
| 510 |
</div>
|
| 511 |
</div>
|
| 512 |
|
|
@@ -516,7 +530,7 @@ permalink: /search/
|
|
| 516 |
<button type="button" class="intent" data-intent="tts">TTS</button>
|
| 517 |
<button type="button" class="intent" data-intent="nlp">NLP</button>
|
| 518 |
<button type="button" class="intent" data-intent="mt">Translation</button>
|
| 519 |
-
<button type="button" class="intent" data-intent="verified">Verified
|
| 520 |
</div>
|
| 521 |
</section>
|
| 522 |
|
|
@@ -570,6 +584,113 @@ permalink: /search/
|
|
| 570 |
intents: [...document.querySelectorAll(".intent")]
|
| 571 |
};
|
| 572 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 573 |
function esc(value) {
|
| 574 |
return String(value || "")
|
| 575 |
.replace(/&/g, "&")
|
|
@@ -583,7 +704,7 @@ permalink: /search/
|
|
| 583 |
return [...new Set(values.filter(Boolean))].sort((a, b) => a.localeCompare(b));
|
| 584 |
}
|
| 585 |
|
| 586 |
-
function fillSelect(select, options, allLabel) {
|
| 587 |
select.innerHTML = "";
|
| 588 |
const allOption = document.createElement("option");
|
| 589 |
allOption.value = "";
|
|
@@ -592,7 +713,7 @@ permalink: /search/
|
|
| 592 |
for (const opt of options) {
|
| 593 |
const entry = document.createElement("option");
|
| 594 |
entry.value = opt;
|
| 595 |
-
entry.textContent = opt;
|
| 596 |
select.appendChild(entry);
|
| 597 |
}
|
| 598 |
}
|
|
@@ -680,33 +801,33 @@ permalink: /search/
|
|
| 680 |
els.countText.textContent = `${items.length} result${items.length === 1 ? "" : "s"} of ${state.all.length}`;
|
| 681 |
|
| 682 |
if (!items.length) {
|
| 683 |
-
els.results.innerHTML = '<li class="empty">No
|
| 684 |
return;
|
| 685 |
}
|
| 686 |
|
| 687 |
els.results.innerHTML = items.map((resource) => {
|
| 688 |
const title = esc(resource.title || "Untitled resource");
|
| 689 |
const url = esc(resource.url || "#");
|
| 690 |
-
const summary = esc(resource.summary || "No summary provided.");
|
| 691 |
-
const primaryUse = esc(resource.primary_use || "
|
| 692 |
-
const evidenceText = esc(resource.evidence_text || "
|
| 693 |
const evidenceUrl = esc(resource.evidence_url || resource.url || "#");
|
| 694 |
-
const tasks = (resource.tasks || []).map((t) => esc(t)).join(", ") || "
|
| 695 |
|
| 696 |
return `
|
| 697 |
<li class="card">
|
| 698 |
<div class="chips">
|
| 699 |
-
${chip(resource.category || "unknown", "category")}
|
| 700 |
-
${chip(resource.source || "unknown", "source")}
|
| 701 |
-
${chip(resource.status || "unknown", "status")}
|
| 702 |
</div>
|
| 703 |
<h2 class="title"><a href="${url}" target="_blank" rel="noreferrer">${title}</a></h2>
|
| 704 |
<p class="text">${summary}</p>
|
| 705 |
-
<p class="text"><strong>Primary
|
| 706 |
<p class="tasks"><strong>Tasks:</strong> ${tasks}</p>
|
| 707 |
<div class="meta-links">
|
| 708 |
-
<a class="mini-link" href="${url}" target="_blank" rel="noreferrer">Open
|
| 709 |
-
<a class="mini-link" href="${evidenceUrl}" target="_blank" rel="noreferrer">Pashto
|
| 710 |
</div>
|
| 711 |
</li>
|
| 712 |
`;
|
|
@@ -772,11 +893,11 @@ permalink: /search/
|
|
| 772 |
async function copySearchLink() {
|
| 773 |
try {
|
| 774 |
await navigator.clipboard.writeText(window.location.href);
|
| 775 |
-
els.copyLink.textContent = "Link
|
| 776 |
-
setTimeout(() => { els.copyLink.textContent = "Copy
|
| 777 |
} catch (_error) {
|
| 778 |
-
els.copyLink.textContent = "Copy
|
| 779 |
-
setTimeout(() => { els.copyLink.textContent = "Copy
|
| 780 |
}
|
| 781 |
}
|
| 782 |
|
|
@@ -788,10 +909,10 @@ permalink: /search/
|
|
| 788 |
|
| 789 |
state.all = payload.resources || [];
|
| 790 |
|
| 791 |
-
fillSelect(els.category, uniqSorted(state.all.map((r) => r.category)), "All
|
| 792 |
-
fillSelect(els.source, uniqSorted(state.all.map((r) => r.source)), "All
|
| 793 |
-
fillSelect(els.status, uniqSorted(state.all.map((r) => r.status)), "All
|
| 794 |
-
fillSelect(els.task, uniqSorted(state.all.flatMap((r) => r.tasks || [])), "All
|
| 795 |
|
| 796 |
updateMetrics();
|
| 797 |
|
|
@@ -825,3 +946,6 @@ permalink: /search/
|
|
| 825 |
</script>
|
| 826 |
</body>
|
| 827 |
</html>
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
<meta charset="utf-8">
|
| 11 |
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 12 |
<title>Pashto Resource Search</title>
|
| 13 |
+
<meta name="description" content="Search verified Pashto (Pukhto/Pashto) resources for Automatic Speech Recognition (ASR), Text-to-Speech (TTS), Natural Language Processing (NLP), machine translation, tools, datasets, models, and benchmarks.">
|
| 14 |
<meta name="keywords" content="Pashto resources, Pukhto resources, Pashto datasets, Pashto ASR, Pashto TTS, Pashto NLP, Pashto machine translation, Pashto benchmarks">
|
| 15 |
<meta name="robots" content="index,follow,max-image-preview:large">
|
| 16 |
<link rel="canonical" href="https://musawer1214.github.io/pashto-language-resources/search/">
|
|
|
|
| 28 |
"@type": "CollectionPage",
|
| 29 |
"name": "Pashto Resource Search",
|
| 30 |
"url": "https://musawer1214.github.io/pashto-language-resources/search/",
|
| 31 |
+
"description": "Search verified and candidate Pashto resources for Automatic Speech Recognition (ASR), Text-to-Speech (TTS), Natural Language Processing (NLP), machine translation, tools, datasets, and benchmarks.",
|
| 32 |
"inLanguage": "en",
|
| 33 |
"about": [
|
| 34 |
"Pashto datasets",
|
|
|
|
| 354 |
margin: 0;
|
| 355 |
font-size: 17px;
|
| 356 |
line-height: 1.3;
|
| 357 |
+
overflow-wrap: anywhere;
|
| 358 |
+
word-break: break-word;
|
| 359 |
}
|
| 360 |
|
| 361 |
.title a {
|
| 362 |
color: var(--ink);
|
| 363 |
text-decoration: none;
|
| 364 |
border-bottom: 1px solid transparent;
|
| 365 |
+
display: inline-block;
|
| 366 |
+
max-width: 100%;
|
| 367 |
+
overflow-wrap: anywhere;
|
| 368 |
+
word-break: break-word;
|
| 369 |
}
|
| 370 |
|
| 371 |
.title a:hover { border-bottom-color: currentColor; }
|
|
|
|
| 375 |
color: var(--muted);
|
| 376 |
line-height: 1.48;
|
| 377 |
font-size: 13px;
|
| 378 |
+
overflow-wrap: anywhere;
|
| 379 |
+
word-break: break-word;
|
| 380 |
}
|
| 381 |
|
| 382 |
.meta-links {
|
|
|
|
| 392 |
font-weight: 700;
|
| 393 |
color: var(--brand);
|
| 394 |
text-decoration: none;
|
| 395 |
+
display: inline-block;
|
| 396 |
+
max-width: 100%;
|
| 397 |
+
overflow-wrap: anywhere;
|
| 398 |
+
word-break: break-word;
|
| 399 |
}
|
| 400 |
|
| 401 |
.tasks {
|
| 402 |
font-size: 12px;
|
| 403 |
color: var(--muted);
|
| 404 |
margin: 0;
|
| 405 |
+
overflow-wrap: anywhere;
|
| 406 |
+
word-break: break-word;
|
| 407 |
}
|
| 408 |
|
| 409 |
.empty {
|
|
|
|
| 460 |
<p class="eyebrow">Pukhto / Pashto Resources</p>
|
| 461 |
<h1>Pashto Technology Resource Search</h1>
|
| 462 |
<p class="subtitle">
|
| 463 |
+
Filter verified and candidate resources for Automatic Speech Recognition (ASR), Text-to-Speech (TTS), Natural Language Processing (NLP), translation, tools, and benchmark work.
|
| 464 |
Share search states with URL parameters and jump quickly to high-intent pages.
|
| 465 |
</p>
|
| 466 |
</div>
|
|
|
|
| 472 |
</div>
|
| 473 |
<nav class="quick-links" aria-label="Quick links">
|
| 474 |
<a class="pill-link" href="../">Docs Home</a>
|
| 475 |
+
<a class="pill-link" href="../pashto_datasets.html">Datasets Page</a>
|
| 476 |
+
<a class="pill-link" href="../pashto_asr.html">ASR Page</a>
|
| 477 |
+
<a class="pill-link" href="../pashto_tts.html">TTS Page</a>
|
| 478 |
<a class="pill-link" href="https://github.com/Musawer1214/pashto-language-resources">GitHub</a>
|
| 479 |
<a class="pill-link" href="https://huggingface.co/Musawer14/pashto-language-resources">Hugging Face</a>
|
| 480 |
</nav>
|
|
|
|
| 484 |
<div class="controls">
|
| 485 |
<div class="field search">
|
| 486 |
<label for="q">Search</label>
|
| 487 |
+
<input id="q" type="search" placeholder="Try: Automatic Speech Recognition, PBT_Arab, Translation, Speech, Benchmark" autocomplete="off">
|
| 488 |
</div>
|
| 489 |
<div class="field">
|
| 490 |
<label for="category">Category</label>
|
|
|
|
| 515 |
|
| 516 |
<div class="action-row">
|
| 517 |
<div class="group" role="group" aria-label="Result view mode">
|
| 518 |
+
<button type="button" class="btn active" id="viewGrid">Grid View</button>
|
| 519 |
+
<button type="button" class="btn" id="viewList">List View</button>
|
| 520 |
</div>
|
| 521 |
<div class="group">
|
| 522 |
+
<button type="button" class="btn light" id="clearFilters">Clear Filters</button>
|
| 523 |
+
<button type="button" class="btn brand" id="copyLink">Copy Search Link</button>
|
| 524 |
</div>
|
| 525 |
</div>
|
| 526 |
|
|
|
|
| 530 |
<button type="button" class="intent" data-intent="tts">TTS</button>
|
| 531 |
<button type="button" class="intent" data-intent="nlp">NLP</button>
|
| 532 |
<button type="button" class="intent" data-intent="mt">Translation</button>
|
| 533 |
+
<button type="button" class="intent" data-intent="verified">Verified Only</button>
|
| 534 |
</div>
|
| 535 |
</section>
|
| 536 |
|
|
|
|
| 584 |
intents: [...document.querySelectorAll(".intent")]
|
| 585 |
};
|
| 586 |
|
| 587 |
+
const TASK_LABELS = {
|
| 588 |
+
"asr": "Automatic Speech Recognition (ASR)",
|
| 589 |
+
"tts": "Text-to-Speech (TTS)",
|
| 590 |
+
"nlp": "Natural Language Processing (NLP)",
|
| 591 |
+
"mt": "Machine Translation (MT)",
|
| 592 |
+
"llm": "Large Language Model (LLM)",
|
| 593 |
+
"ocr": "Optical Character Recognition (OCR)",
|
| 594 |
+
"pos-tagging": "Part-of-Speech Tagging",
|
| 595 |
+
"benchmarking": "Benchmarking",
|
| 596 |
+
"classification": "Classification",
|
| 597 |
+
"demo": "Demo",
|
| 598 |
+
"dictionary": "Dictionary",
|
| 599 |
+
"research": "Research",
|
| 600 |
+
"sentiment": "Sentiment Analysis",
|
| 601 |
+
"tooling": "Tooling",
|
| 602 |
+
"translation": "Translation"
|
| 603 |
+
};
|
| 604 |
+
|
| 605 |
+
const CATEGORY_LABELS = {
|
| 606 |
+
"dataset": "Dataset",
|
| 607 |
+
"model": "Model",
|
| 608 |
+
"benchmark": "Benchmark",
|
| 609 |
+
"tool": "Tool",
|
| 610 |
+
"paper": "Paper",
|
| 611 |
+
"project": "Project",
|
| 612 |
+
"code": "Code"
|
| 613 |
+
};
|
| 614 |
+
|
| 615 |
+
const SOURCE_LABELS = {
|
| 616 |
+
"huggingface": "Hugging Face",
|
| 617 |
+
"mozilla": "Mozilla",
|
| 618 |
+
"kaggle": "Kaggle",
|
| 619 |
+
"github": "GitHub",
|
| 620 |
+
"gitlab": "GitLab",
|
| 621 |
+
"arxiv": "arXiv",
|
| 622 |
+
"openalex": "OpenAlex",
|
| 623 |
+
"crossref": "Crossref",
|
| 624 |
+
"zenodo": "Zenodo",
|
| 625 |
+
"dataverse": "Dataverse",
|
| 626 |
+
"datacite": "DataCite",
|
| 627 |
+
"meta": "Meta",
|
| 628 |
+
"other": "Other"
|
| 629 |
+
};
|
| 630 |
+
|
| 631 |
+
const STATUS_LABELS = {
|
| 632 |
+
"verified": "Verified",
|
| 633 |
+
"candidate": "Candidate"
|
| 634 |
+
};
|
| 635 |
+
|
| 636 |
+
function toTitleCase(value) {
|
| 637 |
+
return String(value || "")
|
| 638 |
+
.replace(/[_-]+/g, " ")
|
| 639 |
+
.split(/\s+/)
|
| 640 |
+
.filter(Boolean)
|
| 641 |
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
|
| 642 |
+
.join(" ");
|
| 643 |
+
}
|
| 644 |
+
|
| 645 |
+
function replaceAbbreviation(text, shortForm, expanded) {
|
| 646 |
+
const fullPhrase = expanded.replace(/\s*\([^)]*\)\s*$/, "");
|
| 647 |
+
if (new RegExp(fullPhrase, "i").test(text)) {
|
| 648 |
+
return text;
|
| 649 |
+
}
|
| 650 |
+
return text.replace(new RegExp(`\\b${shortForm}\\b`, "gi"), expanded);
|
| 651 |
+
}
|
| 652 |
+
|
| 653 |
+
function formatDisplayText(value) {
|
| 654 |
+
let text = String(value || "").trim();
|
| 655 |
+
if (!text) return text;
|
| 656 |
+
|
| 657 |
+
text = text
|
| 658 |
+
.replace(/\bhuggingface\b/gi, "Hugging Face")
|
| 659 |
+
.replace(/\bgithub\b/gi, "GitHub")
|
| 660 |
+
.replace(/\bgitlab\b/gi, "GitLab")
|
| 661 |
+
.replace(/\bopenalex\b/gi, "OpenAlex")
|
| 662 |
+
.replace(/\barxiv\b/gi, "arXiv");
|
| 663 |
+
|
| 664 |
+
text = replaceAbbreviation(text, "ASR", "Automatic Speech Recognition (ASR)");
|
| 665 |
+
text = replaceAbbreviation(text, "TTS", "Text-to-Speech (TTS)");
|
| 666 |
+
text = replaceAbbreviation(text, "NLP", "Natural Language Processing (NLP)");
|
| 667 |
+
text = replaceAbbreviation(text, "MT", "Machine Translation (MT)");
|
| 668 |
+
text = replaceAbbreviation(text, "LLM", "Large Language Model (LLM)");
|
| 669 |
+
text = replaceAbbreviation(text, "OCR", "Optical Character Recognition (OCR)");
|
| 670 |
+
|
| 671 |
+
return text.charAt(0).toUpperCase() + text.slice(1);
|
| 672 |
+
}
|
| 673 |
+
|
| 674 |
+
function formatTaskLabel(value) {
|
| 675 |
+
const key = String(value || "").toLowerCase();
|
| 676 |
+
return TASK_LABELS[key] || toTitleCase(value);
|
| 677 |
+
}
|
| 678 |
+
|
| 679 |
+
function formatCategoryLabel(value) {
|
| 680 |
+
const key = String(value || "").toLowerCase();
|
| 681 |
+
return CATEGORY_LABELS[key] || toTitleCase(value);
|
| 682 |
+
}
|
| 683 |
+
|
| 684 |
+
function formatSourceLabel(value) {
|
| 685 |
+
const key = String(value || "").toLowerCase();
|
| 686 |
+
return SOURCE_LABELS[key] || toTitleCase(value);
|
| 687 |
+
}
|
| 688 |
+
|
| 689 |
+
function formatStatusLabel(value) {
|
| 690 |
+
const key = String(value || "").toLowerCase();
|
| 691 |
+
return STATUS_LABELS[key] || toTitleCase(value);
|
| 692 |
+
}
|
| 693 |
+
|
| 694 |
function esc(value) {
|
| 695 |
return String(value || "")
|
| 696 |
.replace(/&/g, "&")
|
|
|
|
| 704 |
return [...new Set(values.filter(Boolean))].sort((a, b) => a.localeCompare(b));
|
| 705 |
}
|
| 706 |
|
| 707 |
+
function fillSelect(select, options, allLabel, labelFormatter = toTitleCase) {
|
| 708 |
select.innerHTML = "";
|
| 709 |
const allOption = document.createElement("option");
|
| 710 |
allOption.value = "";
|
|
|
|
| 713 |
for (const opt of options) {
|
| 714 |
const entry = document.createElement("option");
|
| 715 |
entry.value = opt;
|
| 716 |
+
entry.textContent = labelFormatter(opt);
|
| 717 |
select.appendChild(entry);
|
| 718 |
}
|
| 719 |
}
|
|
|
|
| 801 |
els.countText.textContent = `${items.length} result${items.length === 1 ? "" : "s"} of ${state.all.length}`;
|
| 802 |
|
| 803 |
if (!items.length) {
|
| 804 |
+
els.results.innerHTML = '<li class="empty">No Matches. Try Broadening Filters or Clearing One Filter at a Time.</li>';
|
| 805 |
return;
|
| 806 |
}
|
| 807 |
|
| 808 |
els.results.innerHTML = items.map((resource) => {
|
| 809 |
const title = esc(resource.title || "Untitled resource");
|
| 810 |
const url = esc(resource.url || "#");
|
| 811 |
+
const summary = esc(formatDisplayText(resource.summary || "No summary provided."));
|
| 812 |
+
const primaryUse = esc(formatDisplayText(resource.primary_use || "Not available"));
|
| 813 |
+
const evidenceText = esc(formatDisplayText(resource.evidence_text || "Evidence link"));
|
| 814 |
const evidenceUrl = esc(resource.evidence_url || resource.url || "#");
|
| 815 |
+
const tasks = (resource.tasks || []).map((t) => esc(formatTaskLabel(t))).join(", ") || "Not available";
|
| 816 |
|
| 817 |
return `
|
| 818 |
<li class="card">
|
| 819 |
<div class="chips">
|
| 820 |
+
${chip(formatCategoryLabel(resource.category || "unknown"), "category")}
|
| 821 |
+
${chip(formatSourceLabel(resource.source || "unknown"), "source")}
|
| 822 |
+
${chip(formatStatusLabel(resource.status || "unknown"), "status")}
|
| 823 |
</div>
|
| 824 |
<h2 class="title"><a href="${url}" target="_blank" rel="noreferrer">${title}</a></h2>
|
| 825 |
<p class="text">${summary}</p>
|
| 826 |
+
<p class="text"><strong>Primary Use:</strong> ${primaryUse}</p>
|
| 827 |
<p class="tasks"><strong>Tasks:</strong> ${tasks}</p>
|
| 828 |
<div class="meta-links">
|
| 829 |
+
<a class="mini-link" href="${url}" target="_blank" rel="noreferrer">Open Resource</a>
|
| 830 |
+
<a class="mini-link" href="${evidenceUrl}" target="_blank" rel="noreferrer">Pashto Evidence: ${evidenceText}</a>
|
| 831 |
</div>
|
| 832 |
</li>
|
| 833 |
`;
|
|
|
|
| 893 |
async function copySearchLink() {
|
| 894 |
try {
|
| 895 |
await navigator.clipboard.writeText(window.location.href);
|
| 896 |
+
els.copyLink.textContent = "Link Copied";
|
| 897 |
+
setTimeout(() => { els.copyLink.textContent = "Copy Search Link"; }, 1200);
|
| 898 |
} catch (_error) {
|
| 899 |
+
els.copyLink.textContent = "Copy Failed";
|
| 900 |
+
setTimeout(() => { els.copyLink.textContent = "Copy Search Link"; }, 1200);
|
| 901 |
}
|
| 902 |
}
|
| 903 |
|
|
|
|
| 909 |
|
| 910 |
state.all = payload.resources || [];
|
| 911 |
|
| 912 |
+
fillSelect(els.category, uniqSorted(state.all.map((r) => r.category)), "All Categories", formatCategoryLabel);
|
| 913 |
+
fillSelect(els.source, uniqSorted(state.all.map((r) => r.source)), "All Sources", formatSourceLabel);
|
| 914 |
+
fillSelect(els.status, uniqSorted(state.all.map((r) => r.status)), "All Statuses", formatStatusLabel);
|
| 915 |
+
fillSelect(els.task, uniqSorted(state.all.flatMap((r) => r.tasks || [])), "All Tasks", formatTaskLabel);
|
| 916 |
|
| 917 |
updateMetrics();
|
| 918 |
|
|
|
|
| 946 |
</script>
|
| 947 |
</body>
|
| 948 |
</html>
|
| 949 |
+
|
| 950 |
+
|
| 951 |
+
|
pyproject.toml
CHANGED
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
| 4 |
|
| 5 |
[project]
|
| 6 |
name = "pashto-language-resources"
|
| 7 |
-
version = "1.
|
| 8 |
description = "Open Pashto language resources for ASR, TTS, NLP, and benchmarks"
|
| 9 |
requires-python = ">=3.10"
|
| 10 |
readme = "README.md"
|
|
@@ -37,3 +37,4 @@ packages = []
|
|
| 37 |
|
| 38 |
|
| 39 |
|
|
|
|
|
|
| 4 |
|
| 5 |
[project]
|
| 6 |
name = "pashto-language-resources"
|
| 7 |
+
version = "1.1.1"
|
| 8 |
description = "Open Pashto language resources for ASR, TTS, NLP, and benchmarks"
|
| 9 |
requires-python = ">=3.10"
|
| 10 |
readme = "README.md"
|
|
|
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
+
|