Skip to content
Closed
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
23 changes: 23 additions & 0 deletions book/metadata-ru.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: "Руководство по Asterisk"
subtitle: "Создаем IP-АТС на Asterisk 22 LTS"
author: "Флавио Е. Гонсалвес"
date: "Второе издание"
lang: ru
documentclass: book
classoption:
- oneside
toc: true
toc-title: "Содержание"
toc-depth: 1
numbersections: true
geometry: "paperwidth=7.5in,paperheight=9.25in,inner=0.75in,outer=0.5in,top=0.6in,bottom=0.6in"
fontsize: 11pt
colorlinks: true
linkcolor: black
urlcolor: blue
# Front cover (EPUB uses this directly; the PDF embeds it as a full first page via interior.tex)
cover-image: "src/images/cover.png"
# Monospace-friendly code blocks
listings: false
...
43 changes: 43 additions & 0 deletions book/translate/PLAN-ru.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# План перевода — Portuguese (pt) & Spanish (es)

Статус: **реализовано.** `book/translate/translate.py` переводит главы с помощью Gemini (модель по умолчанию
`gemini-flash-lite-latest` — самый дешёвый вариант; можно изменить через `GEMINI_TRANSLATE_MODEL`),
кэшируя по хешу содержимого. `book/build.sh` собирает язык с `BOOK_LANG=pt|es`. CI переводит и собирает PT/ES на main/tags,
когда установлен секрет репозитория **`GEMINI_API_KEY`**, и прикрепляет их к релизам.

```bash
python3 book/translate/translate.py --lang ru # -> i18n/ru/chapters/ (cached by hash)
BOOK_LANG=ru bash book/build.sh clean # -> build/asterisk-guide-ru.{pdf,epub,tex}
```

Реализует согласованные спецификации:

## Решения (от автора)

- **Движок:** перевод выполняет Google **Gemini**, используя **тот же API-ключ**, что уже есть в `.env` (тот, что использует иллюстратор) —
считываем его так же, как `book/illustrate/nanobanana.py`. Никогда не коммить ключ.
- **Модель:** **самая дешевая текстовая модель Gemini** (например, `gemini-2.0-flash-lite` / текущий уровень flash-lite).
Сделайте её настраиваемой константой с умолчанием на самую дешевую доступную.
- **Изображения остаются на английском** — **не** переводите и не пересоздавайте изображения. Ссылки `![alt](../images/NAME)` оставляем как есть,
указывая на те же английские картинки. (Перевод alt-текста по желанию; файлы изображений не трогаем.)
- **Целевые языки:** португальский (pt-BR) и испанский (es).

## Подход

1. `book/translate/translate.py` — для каждого `src/chapters/*.md` отправляй Markdown в Gemini со строгим указанием:
переводи только прозаический текст; **не изменяй** блоки кода, встроенный `код`, конфиги, имена опций CLI,
ссылки `![](../images/...)` и структуру Markdown; не переводи технические термины Asterisk (PJSIP, dialplan, `pjsip.conf` и т.д.).
Делай обработку по главам (или по заголовкам), чтобы не превышать лимиты токенов;
кэшируй по хэшу содержимого, чтобы не платить повторно за неизменённые главы.
2. Вывод в `i18n/pt/chapters/` и `i18n/es/chapters/` (одинаковые имена файлов). Иллюстрации берутся из
`src/images/` через `--resource-path`, так что копии изображений для каждого языка не нужны.
3. `book/build.sh` получает параметр `LANG` (по умолчанию `en`); сборка PT/ES делается так же →
`asterisk-guide-pt.{pdf,epub,tex}` и `-es`. Строки передней части/метаданных локализованы.
4. **CI:** расширить `.github/workflows/build-book.yml` с матрицей языков (`[en, pt, es]`);
шаг перевода выполняется только при изменении глав, использует `GEMINI_API_KEY` из **секрета** GitHub Actions,
а перевод на самой дешёвой модели достаточно дешевый, чтобы запускать его для каждого PR. Релизы прикрепляют все три языка.

## Открытые вопросы по времени реализации
- pt-BR против pt-PT (предположим **pt-BR**).
- Нужно ли также локализовать альтернативный текст для изображений (дешево; сами изображения остаются на английском).
- Глоссарий терминов, которые нужно оставлять на английском (PJSIP, dialplan, channel, trunk, …).
2 changes: 1 addition & 1 deletion book/translate/translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def unmask_code(md, blocks):
LLM_API_KEY = os.environ.get("LLM_API_KEY") or os.environ.get("SIPPULSE_API_KEY") # Bearer, optional
LLM_REASONING = os.environ.get("LLM_REASONING") # e.g. "low" for gpt-oss; unset for others
LANG_NAMES = {"pt": "Brazilian Portuguese (pt-BR)", "es": "Latin American Spanish (es)",
"fr": "French", "de": "German", "it": "Italian", "hi": "Hindi",
"fr": "French", "de": "German", "it": "Italian", "hi": "Hindi", "ru": "Russian",
"zh": "Simplified Chinese (Mandarin)", "ja": "Japanese",
"ar": "Modern Standard Arabic"}
HERE = os.path.dirname(os.path.abspath(__file__))
Expand Down
Loading