Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/ISSUE_TEMPLATE/glossary_searcher_bug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
name: اشکال در واژه‌یاب
about: گزارش مشکل یا رفتار نادرست در ابزار واژه‌یاب
title: "[واژه‌یاب] "
labels: bug
assignees: ''
---

## توضیح مشکل

<!--
لطفاً مشکل مشاهده‌شده را به‌طور کامل توضیح دهید.
اگر ممکن است، مراحل لازم برای بازتولید مشکل را نیز بنویسید.
-->

## مراحل بازتولید

<!--
مراحل انجام‌شده برای مشاهده‌ی مشکل را به‌ترتیب وارد کنید.
برای مثال:
1. به صفحه‌ی واژه‌یاب بروید.
2. واژه‌ی خاصی را جست‌وجو کنید.
3. نتیجه‌ی نادرست یا خطا را مشاهده کنید.
-->

## نتیجه‌ی مورد انتظار

<!--
توضیح دهید انتظار داشتید واژه‌یاب چه رفتاری داشته باشد.
-->

## نتیجه‌ی مشاهده‌شده

<!--
توضیح دهید واژه‌یاب در عمل چه رفتاری نشان داد.
-->

## مرورگر و محیط مورد استفاده

<!--
لطفاً اطلاعات مربوط به محیط اجرا را وارد کنید.
برای مثال:
- Firefox نسخه‌ی x
- Chrome نسخه‌ی y
- سیستم‌عامل (در صورت ارتباط)
-->

## اسکرین‌شات یا اطلاعات تکمیلی

<!--
در صورت امکان، تصویر، پیام خطا، یا هر اطلاعات دیگری که به بررسی مشکل کمک می‌کند را درج کنید.
-->

## آیین‌نامه‌ی رفتاری

- [ ] می‌پذیرم که از [آیین‌نامه‌ی رفتاری PSF](https://www.python.org/psf/conduct/) پیروی کنم.
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
- [ ] `msgfmt --check` روی پرونده‌های تغییر یافته با موفقیت اجرا شده است
- [ ] `python3 scripts/check_markup.py` روی پرونده‌های تغییر یافته اجرا شده است
- [ ] نشانه‌گذاری‌های Sphinx (`:class:`، `:func:`، کد درون‌خطی) و جای‌گذارها (`%s`، `{name}`) دست‌نخورده مانده‌اند
- [ ] ترجمه‌ها با [واژه‌نامه (GLOSSARY.md)](https://github.com/python/python-docs-fa/blob/3.14/GLOSSARY.md) هماهنگ است
- [ ] ترجمه‌ها با [واژه‌نامه](http://python.github.io/python-docs-fa/glossary-searcher) هماهنگ است
- [ ] رشته‌های `fuzzy` بررسی و در صورت لزوم بازنویسی شده‌اند
- [ ] پرونده [CONTRIBUTING.md](https://github.com/python/python-docs-fa/blob/3.14/CONTRIBUTING.md) با دقت خوانده شده است.
<!-- یادآوری: بررسی‌های خودکار (sphinx-lint ،msgfmt ،check_markup و ساخت کامل) در GitHub Actions روی پول‌ریکوئست اجرا می‌شوند. -->
42 changes: 32 additions & 10 deletions .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ name: Build and Deploy to GitHub Pages

on:
schedule:
- cron: '0 2 * * *'
- cron: '0 2 * * *'
push:
branches:
- 3.14
paths-ignore: []
workflow_dispatch:

permissions:
Expand All @@ -26,21 +27,17 @@ jobs:
with:
repository: python/cpython
ref: v3.14.7

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'

- name: Setup virtual environment
run: make venv
working-directory: ./Doc

- name: Pin Sphinx to 9.1.0
# make venv may resolve an older Sphinx via requirements.txt; pin
# explicitly so we get the reordered-ref / translated-display-text
# i18n fixes (sphinx-doc/sphinx#14144). Bump this once #14162 lands
# upstream and re-check whether the suppression below is still needed.
run: ./venv/bin/pip install "sphinx==9.1.0"
working-directory: ./Doc

Expand All @@ -56,14 +53,39 @@ jobs:

- name: Setup problem matcher
uses: sphinx-doc/github-problem-matcher@v1.1

- name: Build documentation
run: make -e SPHINXERRORHANDLING="" SPHINXOPTS="--color -D language='fa' -D gettext_allow_fuzzy_translations=1 -D html_theme_options.is_rtl=true -D suppress_warnings=i18n.inconsistent_references --keep-going" html
working-directory: ./Doc


# ---- Glossary searcher build starts here ----
- name: Install glossary build dependencies
run: pip install -r glossary-searcher/scripts/requirements.txt
working-directory: Doc/locales/fa/LC_MESSAGES

- name: Build glossary corpus & glossary data
run: |
python glossary-searcher/scripts/build_corpus.py \
--repo-dir . \
--glossary-tsv glossary.tsv \
--out-dir glossary-searcher/data
working-directory: Doc/locales/fa/LC_MESSAGES

- name: Build glossary site
run: |
python glossary-searcher/scripts/build_site.py \
--site-dir glossary-searcher/site \
--data-dir glossary-searcher/data \
--out-dir glossary-searcher/dist
working-directory: Doc/locales/fa/LC_MESSAGES

- name: Merge glossary site into docs build
run: cp -r Doc/locales/fa/LC_MESSAGES/glossary-searcher/dist Doc/build/html/glossary-searcher
# ---- Glossary searcher build ends here ----

- name: Setup Pages
uses: actions/configure-pages@v4

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
Expand Down
12 changes: 7 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# راهنمای مشارکت در ترجمه‌ی مستندات پایتون

این راهنما مکمل [README.md](README.md) است و جزئیات فنی و فرایندهای پروژه را توضیح می‌دهد. پیش از شروع، حتماً [README.md](README.md) را بخوانید.
این راهنما مکمل [README.md](README.md) است و جزئیات فنی و فرایندهای مربوط به مشارکت در پروژه را توضیح می‌دهد. پیش از شروع مشارکت، حتماً [README.md](README.md) را مطالعه کنید.

همچنین واژه‌نامه‌ی پروژه به‌صورت یک وبگاه از طریق [این پیوند](http://python.github.io/python-docs-fa/glossary-searcher) در دسترس است. با جست‌وجوی واژه‌ی انگلیسی مورد نظر، می‌توانید در صورت وجود آن در واژه‌نامه، معادل فارسی ثبت‌شده‌ی آن را به‌همراه نمونه‌های کاربرد آن در پیکره‌ی مستندات مشاهده کنید.

تمام مشارکت‌کنندگان موظف‌اند از [آیین‌نامه‌ی رفتاری PSF](https://www.python.org/psf/conduct/) پیروی کنند. این تعهد در همه‌ی ایشیوها و پول‌ریکوئست‌ها به‌صورت یک چک‌باکس ثبت می‌شود.

Expand Down Expand Up @@ -38,10 +40,11 @@

## انواع ایشیو

پیش از باز کردن ایشیوی جدید، قالب مناسب را از [صفحه‌ی ایشیوهای پروژه](https://github.com/python/python-docs-fa/issues/new/choose) انتخاب کنید. دو قالب موجود است:
پیش از باز کردن ایشیوی جدید، قالب مناسب را از [صفحه‌ی ایشیوهای پروژه](https://github.com/python/python-docs-fa/issues/new/choose) انتخاب کنید. سه قالب موجود است:

- **اشکال در ترجمه:** برای گزارش ترجمه‌ی نادرست یا مشکل‌دار در یک صفحه‌ی منتشرشده. `msgid`، `msgstr` فعلی، و ترجمه‌ی پیشنهادی خود را در قالب وارد کنید.
- **پیشنهاد تغییرات در ترجمه:** برای پیشنهاد تغییر در یک واژه یا شیوه‌ی نگارشِ ثابت‌شده (نه یک اشکال ساده). فرایند بررسی این نوع پیشنهاد در بخش [«پیشنهاد تغییر در واژه یا شیوه‌ی نگارش»](#پیشنهاد-تغییر-در-واژه-یا-شیوهی-نگارش) توضیح داده شده است.
- **گزارش اشکال در واژه‌یاب:** برای گزارش اشکالات در واژه‌یاب، از این قالب استفاده کنید.

## فرایند ترجمه

Expand All @@ -52,7 +55,7 @@

3. متن `msgid` را ترجمه کنید و در `msgstr` وارد کنید.

4. برای پیدا کردن ترجمه‌ی مناسب برای کلمات و عبارات تخصصی، از [این](https://sepehr-rs.github.io/python-docs-fa-glossary/) پیوند به واژه‌یاب پایتون رفته و واژه/عبارت موردنظر خود را جست‌جو کنید.
4. برای پیدا کردن ترجمه‌ی مناسب برای کلمات و عبارات تخصصی، از [این پیوند](http://python.github.io/python-docs-fa/glossary-searcher) به واژه‌یاب پایتون رفته و واژه/عبارت موردنظر خود را جست‌جو کنید.

5. **نشانه‌گذاری‌های Sphinx** مثل `` :class:`int` ``، `` :func:`repr` ``، `` :ref:`...` ``، `` ``code`` `` و **جای‌گذارها** مثل `%s` یا `{name}` را دقیقاً بدون تغییر نگه دارید؛ فقط متن اطراف آن‌ها ترجمه می‌شود. در `` :term:`target` ``، اگر عبارت داخل بک‌تیک با شناسه‌ی واژه‌نامه یکی است، می‌توانید آن را به شکل `` :term:`ترجمه <target>` `` بنویسید تا هم متن ترجمه‌شده نمایش داده شود و هم لینک درست کار کند؛ در این حالت فقط بخش نمایشی (پیش از `<`) ترجمه می‌شود و `target` داخل `<>` باید دقیقاً همان شناسه‌ی انگلیسی اصلی (بدون تغییر) باقی بماند، چون تغییر آن لینک را خراب می‌کند.

Expand Down Expand Up @@ -190,5 +193,4 @@ python3 scripts/update_python_version.py v3.15.0 --keep-src

پیشنهادهای افزودن واژه‌ی جدید نیز پس از بررسی اولیه‌ی نگهدارندگان، در صورت نیاز از همان فرایند نظرسنجی توضیح داده شده در بالا استفاده خواهند کرد تا درباره‌ی پذیرش یا رد آن تصمیم‌گیری شود.

## گزارش اشکال در واژه‌یاب
لطفا برای گزارش اشکال در واژه‌یاب به مخزن [python-docs-fa-glossary](https://github.com/sepehr-rs/python-docs-fa-glossary) مراجعه کنید.
مشارکت‌ها به واژه‌نامه باید به پرونده‌ی `glossary.tsv` انجام شوند.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
پیش از شروع، حتماً نگاهی به این پرونده‌ها بیندازید:

- [CONTRIBUTING.md](CONTRIBUTING.md) — راهنمای کامل مشارکت: انواع ایشیو، نکات نگارشی و تایپوگرافی فارسی، سطح رسمیت و لحن نوشتار، اندازه‌ی پول‌ریکوئست، فرایند بازبینی و تأیید پول‌ریکوئست، همگام‌سازی با نسخه‌های جدید پایتون (`scripts/update_python_version.py`)، پاک‌سازی رشته‌های `fuzzy` و نگهداری اعتبار مترجمان در سرآیند پرونده‌های `.po`.
- [GLOSSARY.md](GLOSSARY.md) — واژه‌نامه‌ی معادل‌های فارسی اصطلاحات تخصصی؛ هنگام ترجمه باید به آن پایبند باشید.

- [واژه‌یاب](http://python.github.io/python-docs-fa/glossary-searcher) — ابزار جست‌وجوی واژگان تخصصی مستندات پایتون؛ هنگام ترجمه می‌توانید از آن برای یافتن معادل‌های فارسی ثبت‌شده و مشاهده‌ی نمونه‌های کاربرد واژگان در پیکره‌ی مستندات استفاده کنید.

- [TEAM.md](TEAM.md) — فهرست هماهنگ‌کننده‌ها، بازبین‌ها و مترجمان به‌همراه آمار مشارکت.

- [STATUS.md](STATUS.md) — جدول وضعیت ترجمه‌ی پرونده‌ها که به‌صورت خودکار به‌روزرسانی می‌شود.

### شاخه‌های نسخه
Expand Down
1 change: 1 addition & 0 deletions glossary-searcher/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
150 changes: 150 additions & 0 deletions glossary-searcher/scripts/build_corpus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#!/usr/bin/env python3
"""
Builds corpus.json and glossary.json from the python/python-docs-fa repository.

corpus.json shape (consumed by the glossary searcher site):
[ { "msgid": "...", "msgstr": "...", "file": "library/functions.po", "line": 123 }, ... ]

glossary.json shape:
[ { "en": "decorator", "fa": "دکوراتور، آراینده" }, ... ]

Usage:
python build_corpus.py --repo-dir ./python-docs-fa --glossary-tsv ./glossary.tsv --out-dir ./data
"""
import argparse
import csv
import json
import os
import sys

try:
import polib
except ImportError:
print("ERROR: polib is required. Install with: pip install polib", file=sys.stderr)
sys.exit(1)


def find_po_files(repo_dir):
po_files = []
for root, _dirs, files in os.walk(repo_dir):
# skip VCS/meta directories
if "/.git" in root or root.endswith("/.git"):
continue
for fname in files:
if fname.endswith(".po"):
full_path = os.path.join(root, fname)
rel_path = os.path.relpath(full_path, repo_dir)
po_files.append((full_path, rel_path))
return sorted(po_files, key=lambda x: x[1])


def parse_po_files(repo_dir):
"""Parse every .po file into flattened msgid/msgstr corpus entries."""
entries = []
skipped = 0
po_files = find_po_files(repo_dir)

if not po_files:
print(f"WARNING: no .po files found under {repo_dir}", file=sys.stderr)

for full_path, rel_path in po_files:
try:
po = polib.pofile(full_path)
except Exception as e:
print(f"WARNING: failed to parse {rel_path}: {e}", file=sys.stderr)
skipped += 1
continue

for entry in po:
# Skip obsolete, fuzzy, or empty-translation entries -- they
# aren't useful corpus results and fuzzy ones are unreviewed.
if entry.obsolete:
continue
if "fuzzy" in entry.flags:
continue
if not entry.msgid or not entry.msgstr:
continue

entries.append(
{
"msgid": entry.msgid,
"msgstr": entry.msgstr,
"file": rel_path,
"line": entry.linenum if hasattr(entry, "linenum") else 0,
}
)

print(
f"Parsed {len(po_files)} .po files ({skipped} skipped), "
f"{len(entries)} translated entries",
file=sys.stderr,
)
return entries


def parse_glossary_tsv(tsv_path):
"""Parse the glossary TSV (English<TAB>Persian) into glossary.json entries."""
entries = []
with open(tsv_path, "r", encoding="utf-8") as f:
reader = csv.reader(f, delimiter="\t")
rows = list(reader)

if not rows:
return entries

# Skip header row if it looks like one
start_idx = 1 if rows[0][:2] == ["English", "Persian"] else 0

for row in rows[start_idx:]:
if len(row) < 2:
continue
en, fa = row[0].strip(), row[1].strip()
if en and fa:
entries.append({"en": en, "fa": fa})

print(f"Parsed {len(entries)} glossary entries", file=sys.stderr)
return entries


def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--repo-dir", required=True, help="Path to the cloned python-docs-fa checkout"
)
parser.add_argument(
"--glossary-tsv",
required=True,
help="Path to the glossary TSV file (English<TAB>Persian)",
)
parser.add_argument(
"--out-dir",
required=True,
help="Directory to write corpus.json and glossary.json into",
)
args = parser.parse_args()

os.makedirs(args.out_dir, exist_ok=True)

corpus = parse_po_files(args.repo_dir)
glossary = parse_glossary_tsv(args.glossary_tsv)

corpus_path = os.path.join(args.out_dir, "corpus.json")
glossary_path = os.path.join(args.out_dir, "glossary.json")

with open(corpus_path, "w", encoding="utf-8") as f:
json.dump(corpus, f, ensure_ascii=False, separators=(",", ":"))

with open(glossary_path, "w", encoding="utf-8") as f:
json.dump(glossary, f, ensure_ascii=False, separators=(",", ":"))

print(
f"Wrote {corpus_path} ({os.path.getsize(corpus_path):,} bytes)", file=sys.stderr
)
print(
f"Wrote {glossary_path} ({os.path.getsize(glossary_path):,} bytes)",
file=sys.stderr,
)


if __name__ == "__main__":
main()
Loading
Loading