mirror of
https://github.com/Azure/co-op-translator
synced 2026-08-09 12:00:08 +00:00
Docs: Add MkDocs API and CLI documentation site (#407)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
name: Publish documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
paths:
|
||||
- "docs/**"
|
||||
- "mkdocs.yml"
|
||||
- "requirements-docs.txt"
|
||||
- ".github/workflows/docs.yml"
|
||||
pull_request:
|
||||
paths:
|
||||
- "docs/**"
|
||||
- "mkdocs.yml"
|
||||
- "requirements-docs.txt"
|
||||
- ".github/workflows/docs.yml"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: pages
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Install documentation dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements-docs.txt
|
||||
|
||||
- name: Build documentation
|
||||
run: mkdocs build --strict
|
||||
|
||||
- name: Upload Pages artifact
|
||||
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: site
|
||||
|
||||
deploy:
|
||||
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
+2
-1
@@ -409,6 +409,7 @@ venv.bak/
|
||||
|
||||
# Generated output
|
||||
dist
|
||||
site/
|
||||
|
||||
# PyCharm
|
||||
.idea/
|
||||
@@ -426,4 +427,4 @@ test_docs/
|
||||
# .DS Store
|
||||
.DS_Store
|
||||
|
||||
.python-version
|
||||
.python-version
|
||||
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
# Python API
|
||||
|
||||
The stable public Python API is intentionally small. The package exports `run_translation` from `co_op_translator.api`; most lower-level modules under `core`, `config`, and `utils` are implementation details used by the CLI and API entry point.
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
```
|
||||
|
||||
## Public entry point
|
||||
|
||||
::: co_op_translator.api.run_translation
|
||||
|
||||
## Typical usage
|
||||
|
||||
Translate Markdown files in the current project into Korean and Japanese:
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
|
||||
run_translation(
|
||||
language_codes="ko ja",
|
||||
markdown=True,
|
||||
)
|
||||
```
|
||||
|
||||
Translate only notebooks from a specific project root:
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
|
||||
run_translation(
|
||||
language_codes="fr",
|
||||
root_dir="./my-course",
|
||||
notebook=True,
|
||||
)
|
||||
```
|
||||
|
||||
Preview translation volume without writing files:
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
|
||||
run_translation(
|
||||
language_codes="es de",
|
||||
root_dir="./my-course",
|
||||
markdown=True,
|
||||
dry_run=True,
|
||||
)
|
||||
```
|
||||
|
||||
Translate multiple content roots in one call:
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
|
||||
run_translation(
|
||||
language_codes="ko",
|
||||
markdown=True,
|
||||
root_dirs=["./docs", "./labs"],
|
||||
)
|
||||
```
|
||||
|
||||
Write translations into explicit output groups:
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
|
||||
run_translation(
|
||||
language_codes="ja",
|
||||
markdown=True,
|
||||
groups=[
|
||||
("./course-a", "./localized/course-a"),
|
||||
("./course-b", "./localized/course-b"),
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
Use a per-language placeholder when each language should contain a nested subdirectory:
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
|
||||
run_translation(
|
||||
language_codes="ko",
|
||||
markdown=True,
|
||||
groups=[
|
||||
("./course", "./translations/<lang>/course"),
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Default | Purpose |
|
||||
| --- | --- | --- | --- |
|
||||
| `language_codes` | `str` | Required | Space-separated target language codes, such as `"ko ja fr"`, or `"all"`. Alias codes are normalized to canonical BCP 47 values. |
|
||||
| `root_dir` | `str` | `"."` | Project root for a single translation target. Ignored when `root_dirs` or `groups` are supplied. |
|
||||
| `update` | `bool` | `False` | Delete and recreate existing translations for the selected languages. |
|
||||
| `images` | `bool` | `False` | Include image translation. Requires Azure AI Vision configuration. |
|
||||
| `markdown` | `bool` | `False` | Include Markdown translation. |
|
||||
| `notebook` | `bool` | `False` | Include Jupyter notebook translation. |
|
||||
| `debug` | `bool` | `False` | Enable debug logging. |
|
||||
| `save_logs` | `bool` | `False` | Save DEBUG-level log files under the root `logs/` directory. |
|
||||
| `yes` | `bool` | `True` | Auto-confirm prompts for programmatic and CI usage. |
|
||||
| `add_disclaimer` | `bool` | `False` | Add machine translation disclaimers to translated Markdown and notebooks. |
|
||||
| `translations_dir` | `str \| None` | `None` | Custom text translation output directory. Relative paths resolve against each root. |
|
||||
| `image_dir` | `str \| None` | `None` | Custom translated image output directory. Relative paths resolve against each root. |
|
||||
| `root_dirs` | `Iterable[str] \| None` | `None` | Multiple roots that share the same output settings. |
|
||||
| `groups` | `Iterable[tuple[str, str \| None]] \| None` | `None` | Explicit `(root_dir, translations_dir)` pairs. Takes precedence over `root_dirs`. |
|
||||
| `repo_url` | `str \| None` | `None` | Repository URL used when rendering README language table guidance. |
|
||||
| `glossaries` | `Iterable[str] \| None` | `None` | Glossary terms to preserve during translation. Duplicates and blank terms are normalized. |
|
||||
| `dry_run` | `bool` | `False` | Estimate translation volume and preview migration behavior without writing files. |
|
||||
|
||||
If none of `markdown`, `notebook`, or `images` are set, the API translates all supported types: Markdown, notebooks, and images.
|
||||
|
||||
## Configuration requirements
|
||||
|
||||
`run_translation` checks configuration before translating:
|
||||
|
||||
- An LLM provider is required. Configure either Azure OpenAI or OpenAI.
|
||||
- Image translation requires Azure AI Vision in addition to the LLM provider.
|
||||
- The API runs lightweight connectivity checks before translation begins.
|
||||
|
||||
Required Azure OpenAI variables:
|
||||
|
||||
```bash
|
||||
AZURE_OPENAI_API_KEY="..."
|
||||
AZURE_OPENAI_ENDPOINT="https://<resource>.openai.azure.com/"
|
||||
AZURE_OPENAI_MODEL_NAME="gpt-4o"
|
||||
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME="<deployment>"
|
||||
AZURE_OPENAI_API_VERSION="2024-12-01-preview"
|
||||
```
|
||||
|
||||
Required OpenAI variables:
|
||||
|
||||
```bash
|
||||
OPENAI_API_KEY="..."
|
||||
OPENAI_CHAT_MODEL_ID="gpt-4o"
|
||||
```
|
||||
|
||||
Required Azure AI Vision variables for image translation:
|
||||
|
||||
```bash
|
||||
AZURE_AI_SERVICE_API_KEY="..."
|
||||
AZURE_AI_SERVICE_ENDPOINT="https://<resource>.cognitiveservices.azure.com/"
|
||||
```
|
||||
|
||||
## Behavior notes
|
||||
|
||||
- The API prints progress and estimate summaries through Click, matching the CLI user experience.
|
||||
- `dry_run=True` computes estimates using virtual README updates, but does not write the README or translation files.
|
||||
- `groups` are processed sequentially. A single aggregate estimate is printed before work begins.
|
||||
- When image translation is selected, missing Vision configuration raises an error before translation starts.
|
||||
- Existing alias-based language folders are detected and can be migrated to canonical language folder names as part of the run.
|
||||
|
||||
## Internal call path
|
||||
|
||||
The API delegates to the same core implementation used by the CLI:
|
||||
|
||||
1. `co_op_translator.api.translation.run_translation`
|
||||
2. `co_op_translator.config.Config`, `LLMConfig`, and `VisionConfig`
|
||||
3. `co_op_translator.core.project.ProjectTranslator`
|
||||
4. `co_op_translator.core.project.TranslationManager`
|
||||
5. Markdown, notebook, text, and image translators under `co_op_translator.core`
|
||||
|
||||
The following classes are useful for maintainers, but are not exported as the package-level stable API.
|
||||
|
||||
| Class | Module | Responsibility |
|
||||
| --- | --- | --- |
|
||||
| `ProjectTranslator` | `co_op_translator.core.project.project_translator` | Coordinates project-level translation, directory management, per-language metadata normalization, and delegation to Markdown, notebook, and image translators. |
|
||||
| `TranslationManager` | `co_op_translator.core.project.translation_manager` | Performs the async file processing work for Markdown, notebooks, images, stale detection, and translation metadata updates. |
|
||||
| `ProjectEvaluator` | `co_op_translator.core.project.project_evaluator` | Finds translated Markdown pairs, evaluates translation quality, and reads confidence metadata for low-confidence repair workflows. |
|
||||
| `LanguageFolderMigrator` | `co_op_translator.core.project.language_migrator` | Detects legacy alias language folders and prepares canonical BCP 47 folder migration plans. |
|
||||
| `Config` | `co_op_translator.config.base_config` | Loads `.env` files and checks whether required LLM and optional Vision providers are configured. |
|
||||
| `LLMConfig` | `co_op_translator.config.llm_config.config` | Auto-detects Azure OpenAI or OpenAI, validates required environment variables, and runs provider connectivity checks. |
|
||||
| `VisionConfig` | `co_op_translator.config.vision_config.config` | Detects Azure AI Vision configuration and runs connectivity checks for image translation. |
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
+206
@@ -0,0 +1,206 @@
|
||||
# CLI Reference
|
||||
|
||||
Co-op Translator installs three command-line entry points:
|
||||
|
||||
- `translate`
|
||||
- `evaluate`
|
||||
- `migrate-links`
|
||||
|
||||
The dispatch logic lives in `co_op_translator.__main__`, which selects the command implementation based on the invoked script name.
|
||||
|
||||
## translate
|
||||
|
||||
Translate Markdown files, notebooks, and image text into one or more target languages.
|
||||
|
||||
```bash
|
||||
translate -l "ko ja fr"
|
||||
```
|
||||
|
||||
### Common examples
|
||||
|
||||
Translate only Markdown:
|
||||
|
||||
```bash
|
||||
translate -l "de" -md
|
||||
```
|
||||
|
||||
Translate only notebooks:
|
||||
|
||||
```bash
|
||||
translate -l "zh-CN" -nb
|
||||
```
|
||||
|
||||
Translate Markdown and images:
|
||||
|
||||
```bash
|
||||
translate -l "pt-BR" -md -img
|
||||
```
|
||||
|
||||
Update existing translations by deleting and recreating them:
|
||||
|
||||
```bash
|
||||
translate -l "ko" -u
|
||||
```
|
||||
|
||||
Run without interactive prompts:
|
||||
|
||||
```bash
|
||||
translate -l "ko ja" -md -y
|
||||
```
|
||||
|
||||
Save logs:
|
||||
|
||||
```bash
|
||||
translate -l "ko" -s
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Required | Description |
|
||||
| --- | --- | --- |
|
||||
| `-l`, `--language-codes` | Yes | Space-separated language codes, such as `"es fr de"`, or `"all"`. |
|
||||
| `-r`, `--root-dir` | No | Project root. Defaults to the current directory. |
|
||||
| `-u`, `--update` | No | Delete existing translations for selected languages and recreate them. |
|
||||
| `-img`, `--images` | No | Translate only image files. |
|
||||
| `-md`, `--markdown` | No | Translate only Markdown files. |
|
||||
| `-nb`, `--notebook` | No | Translate only Jupyter notebook files. |
|
||||
| `-d`, `--debug` | No | Enable debug logging in the console. |
|
||||
| `-s`, `--save-logs` | No | Save DEBUG-level logs under `<root-dir>/logs/`. |
|
||||
| `-x`, `--fix` | No | Retranslate low-confidence Markdown files based on previous evaluation results. |
|
||||
| `-c`, `--min-confidence` | No | Confidence threshold for `--fix`. Defaults to `0.7`. |
|
||||
| `--add-disclaimer`, `--no-disclaimer` | No | Add or suppress machine translation disclaimers. Defaults to enabled in the CLI. |
|
||||
| `-f`, `--fast` | No | Deprecated fast image mode. |
|
||||
| `-y`, `--yes` | No | Auto-confirm prompts, useful in CI. |
|
||||
| `--repo-url` | No | Repository URL used in the README languages table sparse-checkout advisory. |
|
||||
| `--migrate-language-folders` | No | Rename legacy alias folders, such as `cn` or `tw`, to canonical BCP 47 folders. |
|
||||
| `--dry-run` | No | Preview language folder migration and translation estimates without writing files. |
|
||||
|
||||
If no type flag is provided, `translate` processes Markdown, notebooks, and images. Image translation requires Azure AI Vision configuration.
|
||||
|
||||
## evaluate
|
||||
|
||||
Evaluate translated Markdown quality for one language.
|
||||
|
||||
```bash
|
||||
evaluate -l "ko"
|
||||
```
|
||||
|
||||
### Common examples
|
||||
|
||||
Use a stricter low-confidence threshold:
|
||||
|
||||
```bash
|
||||
evaluate -l "es" -c 0.8
|
||||
```
|
||||
|
||||
Run rule-based checks only:
|
||||
|
||||
```bash
|
||||
evaluate -l "fr" -f
|
||||
```
|
||||
|
||||
Run LLM-based checks only:
|
||||
|
||||
```bash
|
||||
evaluate -l "ja" -D
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Required | Description |
|
||||
| --- | --- | --- |
|
||||
| `-l`, `--language-code` | Yes | Single language code to evaluate. Alias codes are normalized. |
|
||||
| `-r`, `--root-dir` | No | Project root. Defaults to the current directory. |
|
||||
| `-c`, `--min-confidence` | No | Threshold used when listing low-confidence translations. Defaults to `0.7`. |
|
||||
| `-d`, `--debug` | No | Enable debug logging. |
|
||||
| `-s`, `--save-logs` | No | Save DEBUG-level logs under `<root-dir>/logs/`. |
|
||||
| `-f`, `--fast` | No | Rule-based evaluation only. |
|
||||
| `-D`, `--deep` | No | LLM-based evaluation only. |
|
||||
|
||||
By default, `evaluate` uses both rule-based and LLM-based evaluation. Results are written into translation metadata and summarized in the console.
|
||||
|
||||
## migrate-links
|
||||
|
||||
Reprocess translated Markdown files and update notebook links so they point to translated notebooks when available.
|
||||
|
||||
```bash
|
||||
migrate-links -l "ko ja"
|
||||
```
|
||||
|
||||
### Common examples
|
||||
|
||||
Preview link updates:
|
||||
|
||||
```bash
|
||||
migrate-links -l "ko" --dry-run
|
||||
```
|
||||
|
||||
Process all supported languages without confirmation:
|
||||
|
||||
```bash
|
||||
migrate-links -l "all" -y
|
||||
```
|
||||
|
||||
Only rewrite links when translated notebooks exist:
|
||||
|
||||
```bash
|
||||
migrate-links -l "ko" --no-fallback-to-original
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Required | Description |
|
||||
| --- | --- | --- |
|
||||
| `-l`, `--language-codes` | Yes | Space-separated language codes, or `"all"`. |
|
||||
| `-r`, `--root-dir` | No | Project root. Defaults to the current directory. |
|
||||
| `--image-dir` | No | Translated image directory relative to the root. Defaults to `translated_images`. |
|
||||
| `--dry-run` | No | Show files that would change without writing updates. |
|
||||
| `--fallback-to-original`, `--no-fallback-to-original` | No | Use original notebook links when translated notebooks are missing. Enabled by default. |
|
||||
| `-d`, `--debug` | No | Enable debug logging. |
|
||||
| `-s`, `--save-logs` | No | Save DEBUG-level logs under `<root-dir>/logs/`. |
|
||||
| `-y`, `--yes` | No | Auto-confirm prompts when processing all languages. |
|
||||
|
||||
## Environment
|
||||
|
||||
All commands require one configured LLM provider:
|
||||
|
||||
```bash
|
||||
# Azure OpenAI
|
||||
AZURE_OPENAI_API_KEY="..."
|
||||
AZURE_OPENAI_ENDPOINT="https://<resource>.openai.azure.com/"
|
||||
AZURE_OPENAI_MODEL_NAME="gpt-4o"
|
||||
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME="<deployment>"
|
||||
AZURE_OPENAI_API_VERSION="2024-12-01-preview"
|
||||
|
||||
# Or OpenAI
|
||||
OPENAI_API_KEY="..."
|
||||
OPENAI_CHAT_MODEL_ID="gpt-4o"
|
||||
```
|
||||
|
||||
Image translation additionally requires Azure AI Vision:
|
||||
|
||||
```bash
|
||||
AZURE_AI_SERVICE_API_KEY="..."
|
||||
AZURE_AI_SERVICE_ENDPOINT="https://<resource>.cognitiveservices.azure.com/"
|
||||
```
|
||||
|
||||
## Output layout
|
||||
|
||||
Text translations are written under:
|
||||
|
||||
```text
|
||||
translations/<language-code>/<original-path>
|
||||
```
|
||||
|
||||
Translated image output is written under:
|
||||
|
||||
```text
|
||||
translated_images/<language-code>/<original-path>
|
||||
```
|
||||
|
||||
For example, translating `README.md` and `docs/setup.md` into Korean produces:
|
||||
|
||||
```text
|
||||
translations/ko/README.md
|
||||
translations/ko/docs/setup.md
|
||||
```
|
||||
@@ -0,0 +1,134 @@
|
||||
# Configuration
|
||||
|
||||
Co-op Translator requires one language model provider. Image translation additionally requires Azure AI Vision.
|
||||
|
||||
Configuration is read from environment variables. For local projects, place them in a `.env` file at the project root.
|
||||
|
||||
## Local runtime setup
|
||||
|
||||
Use a virtual environment before running the CLI locally. Co-op Translator supports Python 3.10 through 3.12.
|
||||
|
||||
For normal CLI usage, install the published package inside a virtual environment:
|
||||
|
||||
=== "Windows"
|
||||
|
||||
```powershell
|
||||
python -m venv .venv
|
||||
.venv\Scripts\activate
|
||||
pip install co-op-translator
|
||||
translate --help
|
||||
```
|
||||
|
||||
=== "macOS / Linux"
|
||||
|
||||
```bash
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install co-op-translator
|
||||
translate --help
|
||||
```
|
||||
|
||||
For repository development, install dependencies from the project root instead:
|
||||
|
||||
```bash
|
||||
poetry install
|
||||
poetry run translate --help
|
||||
```
|
||||
|
||||
After the CLI is available, configure one language model provider in `.env`.
|
||||
|
||||
## Provider selection
|
||||
|
||||
The tool auto-detects providers in this order:
|
||||
|
||||
1. Azure OpenAI
|
||||
2. OpenAI
|
||||
|
||||
If neither provider is configured, `translate`, `evaluate`, `migrate-links`, and `run_translation` fail during configuration checks.
|
||||
|
||||
## Azure OpenAI
|
||||
|
||||
Use Azure OpenAI when your model is deployed in Azure AI Foundry or Azure OpenAI Service.
|
||||
|
||||
```bash
|
||||
AZURE_OPENAI_API_KEY="..."
|
||||
AZURE_OPENAI_ENDPOINT="https://<resource>.openai.azure.com/"
|
||||
AZURE_OPENAI_MODEL_NAME="gpt-4o"
|
||||
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME="<deployment>"
|
||||
AZURE_OPENAI_API_VERSION="2024-12-01-preview"
|
||||
```
|
||||
|
||||
The connectivity check uses the endpoint, API key, API version, and deployment name before translation begins.
|
||||
|
||||
## OpenAI
|
||||
|
||||
Use OpenAI when calling the OpenAI API directly.
|
||||
|
||||
```bash
|
||||
OPENAI_API_KEY="..."
|
||||
OPENAI_CHAT_MODEL_ID="gpt-4o"
|
||||
OPENAI_ORG_ID="..." # optional
|
||||
OPENAI_BASE_URL="..." # optional
|
||||
```
|
||||
|
||||
`OPENAI_CHAT_MODEL_ID` is required because the translator needs an explicit chat model for API calls.
|
||||
|
||||
## Azure AI Vision
|
||||
|
||||
Image translation requires Azure AI Vision so the tool can extract text from images before translating it.
|
||||
|
||||
```bash
|
||||
AZURE_AI_SERVICE_API_KEY="..."
|
||||
AZURE_AI_SERVICE_ENDPOINT="https://<resource>.cognitiveservices.azure.com/"
|
||||
```
|
||||
|
||||
If image translation is selected with `-img`, `images=True`, or no content-type filter, the tool validates Vision configuration before translation starts.
|
||||
|
||||
## Multiple credential sets
|
||||
|
||||
The configuration layer supports multiple credential sets by suffixing variables with the same index:
|
||||
|
||||
```bash
|
||||
AZURE_OPENAI_API_KEY_1="..."
|
||||
AZURE_OPENAI_ENDPOINT_1="https://<resource-1>.openai.azure.com/"
|
||||
AZURE_OPENAI_MODEL_NAME_1="gpt-4o"
|
||||
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME_1="<deployment-1>"
|
||||
AZURE_OPENAI_API_VERSION_1="2024-12-01-preview"
|
||||
|
||||
AZURE_OPENAI_API_KEY_2="..."
|
||||
AZURE_OPENAI_ENDPOINT_2="https://<resource-2>.openai.azure.com/"
|
||||
AZURE_OPENAI_MODEL_NAME_2="gpt-4o"
|
||||
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME_2="<deployment-2>"
|
||||
AZURE_OPENAI_API_VERSION_2="2024-12-01-preview"
|
||||
```
|
||||
|
||||
Each set must be complete. The health check selects a working set before translation proceeds.
|
||||
|
||||
## Command requirements
|
||||
|
||||
| Command or API | LLM required | Vision required | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| `translate -md` | Yes | No | Translates Markdown only. |
|
||||
| `translate -nb` | Yes | No | Translates notebooks only. |
|
||||
| `translate -img` | Yes | Yes | Translates images only. |
|
||||
| `translate` with no type flags | Yes | Yes | Default mode includes Markdown, notebooks, and images. |
|
||||
| `evaluate` | Yes | No | Uses LLM evaluation unless `--fast` is selected. |
|
||||
| `migrate-links` | Yes | No | Performs link migration, but still runs shared configuration checks. |
|
||||
| `run_translation(markdown=True)` | Yes | No | Programmatic Markdown translation. |
|
||||
| `run_translation(images=True)` | Yes | Yes | Programmatic image translation. |
|
||||
|
||||
## Output directories
|
||||
|
||||
Default text translation output:
|
||||
|
||||
```text
|
||||
translations/<language-code>/<source-relative-path>
|
||||
```
|
||||
|
||||
Default translated image output:
|
||||
|
||||
```text
|
||||
translated_images/<language-code>/<source-relative-path>
|
||||
```
|
||||
|
||||
The Python API can override these directories with `translations_dir` and `image_dir`.
|
||||
@@ -0,0 +1,128 @@
|
||||
# Examples
|
||||
|
||||
These examples use the real CLI and Python API entry points from this repository.
|
||||
|
||||
## Translate Markdown with the CLI
|
||||
|
||||
```bash
|
||||
translate -l "ko ja fr" -md
|
||||
```
|
||||
|
||||
This translates Markdown files only and writes output under:
|
||||
|
||||
```text
|
||||
translations/ko/
|
||||
translations/ja/
|
||||
translations/fr/
|
||||
```
|
||||
|
||||
## Translate notebooks only
|
||||
|
||||
```bash
|
||||
translate -l "zh-CN" -nb
|
||||
```
|
||||
|
||||
Notebook links can later be normalized with:
|
||||
|
||||
```bash
|
||||
migrate-links -l "zh-CN"
|
||||
```
|
||||
|
||||
## Translate images only
|
||||
|
||||
```bash
|
||||
translate -l "pt-BR" -img
|
||||
```
|
||||
|
||||
Image translation requires both an LLM provider and Azure AI Vision.
|
||||
|
||||
## Preview without writing files
|
||||
|
||||
```bash
|
||||
translate -l "de es" -md --dry-run
|
||||
```
|
||||
|
||||
Dry runs are useful when checking token estimates, migration plans, or CI wiring.
|
||||
|
||||
## Repair low-confidence translations
|
||||
|
||||
First evaluate translations:
|
||||
|
||||
```bash
|
||||
evaluate -l "ko" -c 0.8
|
||||
```
|
||||
|
||||
Then retranslate Markdown files below the threshold:
|
||||
|
||||
```bash
|
||||
translate -l "ko" --fix -c 0.8 -md
|
||||
```
|
||||
|
||||
## Run from Python
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
|
||||
run_translation(
|
||||
language_codes="ko ja",
|
||||
root_dir="./course",
|
||||
markdown=True,
|
||||
yes=True,
|
||||
)
|
||||
```
|
||||
|
||||
## Translate multiple roots from Python
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
|
||||
run_translation(
|
||||
language_codes="ko",
|
||||
markdown=True,
|
||||
root_dirs=[
|
||||
"./docs",
|
||||
"./labs",
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
## Use explicit output groups
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
|
||||
run_translation(
|
||||
language_codes="ja",
|
||||
markdown=True,
|
||||
groups=[
|
||||
("./course-a", "./localized/course-a"),
|
||||
("./course-b", "./localized/course-b"),
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
## Preserve glossary terms
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
|
||||
run_translation(
|
||||
language_codes="fr",
|
||||
markdown=True,
|
||||
glossaries=[
|
||||
"Co-op Translator",
|
||||
"Azure AI Foundry",
|
||||
"GitHub Actions",
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
Glossary terms are scoped to the API call and restored afterward.
|
||||
|
||||
## CI-friendly translation command
|
||||
|
||||
```bash
|
||||
translate -l "ko ja" -md -y -s
|
||||
```
|
||||
|
||||
This auto-confirms prompts and saves DEBUG-level logs under `logs/`.
|
||||
@@ -0,0 +1,42 @@
|
||||
<section class="home-hero">
|
||||
<p class="home-eyebrow">Getting started</p>
|
||||
<h1>Co-op Translator Documentation</h1>
|
||||
<p class="home-lede">
|
||||
Configure an LLM provider, choose your target languages, and use Co-op
|
||||
Translator from the CLI or Python API to keep translated project content
|
||||
synchronized with the source.
|
||||
</p>
|
||||
<a class="home-link" href="cli/">Start with the CLI -></a>
|
||||
</section>
|
||||
|
||||
## Quick start
|
||||
|
||||
<div class="quickstart-grid">
|
||||
<a class="quickstart-card" href="configuration/">
|
||||
<span class="quickstart-step">Step 1</span>
|
||||
<strong>Configuration</strong>
|
||||
<span>Set up Azure OpenAI, OpenAI, Azure AI Vision, and output directories.</span>
|
||||
<em>Open guide -></em>
|
||||
</a>
|
||||
|
||||
<a class="quickstart-card" href="cli/">
|
||||
<span class="quickstart-step">Step 2</span>
|
||||
<strong>Translate with CLI</strong>
|
||||
<span>Run translation, evaluation, and link migration commands.</span>
|
||||
<em>Open guide -></em>
|
||||
</a>
|
||||
|
||||
<a class="quickstart-card" href="api/">
|
||||
<span class="quickstart-step">Step 3</span>
|
||||
<strong>Python API</strong>
|
||||
<span>Call <code>run_translation</code> from scripts and automation.</span>
|
||||
<em>Open guide -></em>
|
||||
</a>
|
||||
|
||||
<a class="quickstart-card" href="examples/">
|
||||
<span class="quickstart-step">Step 4</span>
|
||||
<strong>Examples</strong>
|
||||
<span>Copy practical workflows for Markdown, notebooks, images, and repairs.</span>
|
||||
<em>Open guide -></em>
|
||||
</a>
|
||||
</div>
|
||||
@@ -0,0 +1,27 @@
|
||||
window.tailwind = window.tailwind || {};
|
||||
window.tailwind.config = {
|
||||
prefix: "tw-",
|
||||
darkMode: ["selector", '[data-md-color-scheme="slate"]'],
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
coop: {
|
||||
ink: "#172033",
|
||||
blue: "#2563eb",
|
||||
cyan: "#2563eb",
|
||||
mint: "#2563eb",
|
||||
soft: "#f4f8fb",
|
||||
},
|
||||
},
|
||||
boxShadow: {
|
||||
coop: "0 24px 70px rgba(15, 23, 42, 0.12)",
|
||||
},
|
||||
fontFamily: {
|
||||
display: ["Inter", "ui-sans-serif", "system-ui", "sans-serif"],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,112 @@
|
||||
# Maintainer Guide
|
||||
|
||||
This page summarizes how the API, CLI, and documentation site are wired together.
|
||||
|
||||
## Public API boundary
|
||||
|
||||
The stable Python API is exported from:
|
||||
|
||||
```python
|
||||
co_op_translator.api
|
||||
```
|
||||
|
||||
Currently, that package exports:
|
||||
|
||||
```python
|
||||
from co_op_translator.api import run_translation
|
||||
```
|
||||
|
||||
When adding new public APIs, update:
|
||||
|
||||
- `src/co_op_translator/api/__init__.py`
|
||||
- `docs/api.md`
|
||||
- `tests/co_op_translator/test_api.py`
|
||||
|
||||
Avoid documenting lower-level `core` modules as stable API unless the project intends to support them directly.
|
||||
|
||||
## CLI entry points
|
||||
|
||||
The package defines these Poetry scripts:
|
||||
|
||||
```toml
|
||||
[tool.poetry.scripts]
|
||||
translate = "co_op_translator.__main__:main"
|
||||
evaluate = "co_op_translator.__main__:main"
|
||||
migrate-links = "co_op_translator.__main__:main"
|
||||
```
|
||||
|
||||
`src/co_op_translator/__main__.py` dispatches by script name:
|
||||
|
||||
- `translate` calls `co_op_translator.cli.translate.translate_command`
|
||||
- `evaluate` calls `co_op_translator.cli.evaluate.evaluate_command`
|
||||
- `migrate-links` calls `co_op_translator.cli.migrate_links.migrate_links_command`
|
||||
|
||||
When adding or changing CLI options, update:
|
||||
|
||||
- the relevant `src/co_op_translator/cli/*.py` command
|
||||
- `getting_started/command-reference.md`
|
||||
- `docs/cli.md`
|
||||
- CLI-related tests, if behavior changes
|
||||
|
||||
## Translation flow
|
||||
|
||||
The high-level translation flow is:
|
||||
|
||||
1. Parse CLI arguments or API parameters.
|
||||
2. Validate LLM configuration with `LLMConfig`.
|
||||
3. Validate Azure AI Vision when image translation is selected.
|
||||
4. Normalize language codes.
|
||||
5. Detect legacy language folder aliases.
|
||||
6. Estimate translation volume.
|
||||
7. Update README language/course sections when applicable.
|
||||
8. Delegate project translation to `ProjectTranslator`.
|
||||
9. `ProjectTranslator` delegates file processing to `TranslationManager`.
|
||||
|
||||
## Documentation site
|
||||
|
||||
The docs site is configured by:
|
||||
|
||||
```text
|
||||
mkdocs.yml
|
||||
requirements-docs.txt
|
||||
docs/
|
||||
```
|
||||
|
||||
Build locally:
|
||||
|
||||
```bash
|
||||
python -m pip install -r requirements-docs.txt
|
||||
python -m mkdocs build --strict
|
||||
```
|
||||
|
||||
Preview locally:
|
||||
|
||||
```bash
|
||||
python -m mkdocs serve
|
||||
```
|
||||
|
||||
The generated site is written to `site/`, which is ignored by git.
|
||||
|
||||
## GitHub Pages workflow
|
||||
|
||||
`.github/workflows/docs.yml` builds the site on pull requests and deploys it on pushes to `main`.
|
||||
|
||||
The workflow installs:
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
pip install -r requirements-docs.txt
|
||||
```
|
||||
|
||||
Installing runtime dependencies before docs dependencies lets `mkdocstrings` import the package and render the public Python API reference.
|
||||
|
||||
## Docs quality bar
|
||||
|
||||
Before merging documentation changes, run:
|
||||
|
||||
```bash
|
||||
python -m mkdocs build --strict
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Use strict builds so broken links, invalid navigation entries, and API rendering issues fail early.
|
||||
@@ -0,0 +1,636 @@
|
||||
:root {
|
||||
--cot-blue: #2563eb;
|
||||
--cot-cyan: #2563eb;
|
||||
--cot-blue-soft: #3b82f6;
|
||||
--cot-blue-dark: #1d4ed8;
|
||||
--cot-blue-bright: #60a5fa;
|
||||
--cot-ink: #172033;
|
||||
--cot-soft: #f4f8fb;
|
||||
--cot-border: #d8e2ec;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="default"] {
|
||||
--md-primary-fg-color: #2563eb;
|
||||
--md-accent-fg-color: #2563eb;
|
||||
--md-typeset-a-color: #1d4ed8;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] {
|
||||
--md-primary-fg-color: #1d4ed8;
|
||||
--md-accent-fg-color: #60a5fa;
|
||||
}
|
||||
|
||||
.md-header {
|
||||
color: var(--cot-ink);
|
||||
background: rgba(255, 255, 255, 0.96);
|
||||
box-shadow: 0 1px 0 rgba(15, 23, 42, 0.08);
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-header {
|
||||
color: #f8fafc;
|
||||
background: rgba(15, 23, 42, 0.96);
|
||||
box-shadow: 0 1px 0 rgba(148, 163, 184, 0.18);
|
||||
}
|
||||
|
||||
.md-header__title {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.md-header__button,
|
||||
.md-header__topic,
|
||||
.md-header__title,
|
||||
.md-search__icon {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.md-header__button.md-logo img,
|
||||
.md-header__button.md-logo svg {
|
||||
height: 1.7rem;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.md-search__form {
|
||||
color: var(--cot-ink);
|
||||
background-color: #f8fafc;
|
||||
border: 1px solid #cbd5e1;
|
||||
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05);
|
||||
}
|
||||
|
||||
.md-search__form:hover {
|
||||
background-color: #fff;
|
||||
border-color: #94a3b8;
|
||||
}
|
||||
|
||||
.md-search__input {
|
||||
color: var(--cot-ink);
|
||||
}
|
||||
|
||||
.md-search__input::placeholder {
|
||||
color: #64748b;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.md-search__icon,
|
||||
.md-search__icon.md-icon {
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.md-search__icon svg {
|
||||
fill: #1e293b;
|
||||
}
|
||||
|
||||
.md-search__form:hover .md-search__icon,
|
||||
.md-search__form:focus-within .md-search__icon {
|
||||
color: var(--cot-blue);
|
||||
}
|
||||
|
||||
.md-search__form:hover .md-search__icon svg,
|
||||
.md-search__form:focus-within .md-search__icon svg {
|
||||
fill: var(--cot-blue);
|
||||
}
|
||||
|
||||
.md-search__form:focus-within {
|
||||
background-color: #fff;
|
||||
border-color: var(--cot-blue);
|
||||
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.14);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-search__form {
|
||||
color: #f8fafc;
|
||||
background-color: rgba(15, 23, 42, 0.92);
|
||||
border-color: rgba(148, 163, 184, 0.45);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-search__form:hover {
|
||||
background-color: rgba(15, 23, 42, 1);
|
||||
border-color: rgba(148, 163, 184, 0.72);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-search__input {
|
||||
color: #f8fafc;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-search__input::placeholder {
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-search__icon,
|
||||
[data-md-color-scheme="slate"] .md-search__icon.md-icon {
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-search__icon svg {
|
||||
fill: #cbd5e1;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-search__form:hover .md-search__icon,
|
||||
[data-md-color-scheme="slate"] .md-search__form:focus-within .md-search__icon {
|
||||
color: var(--cot-blue-bright);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-search__form:hover .md-search__icon svg,
|
||||
[data-md-color-scheme="slate"] .md-search__form:focus-within .md-search__icon svg {
|
||||
fill: var(--cot-blue-bright);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-search__form:focus-within {
|
||||
border-color: var(--cot-blue-bright);
|
||||
box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.18);
|
||||
}
|
||||
|
||||
.md-nav--primary .md-nav__title[for="__drawer"] {
|
||||
color: var(--cot-ink);
|
||||
background: #f8fafc;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.md-nav--primary .md-nav__title[for="__drawer"] .md-logo {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.md-nav--primary .md-nav__title[for="__drawer"] .md-logo img,
|
||||
.md-nav--primary .md-nav__title[for="__drawer"] .md-logo svg {
|
||||
height: 1.7rem;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-nav--primary .md-nav__title[for="__drawer"] {
|
||||
color: #f8fafc;
|
||||
background: #0f172a;
|
||||
border-bottom-color: rgba(148, 163, 184, 0.2);
|
||||
}
|
||||
|
||||
.md-typeset h1,
|
||||
.md-typeset h2 {
|
||||
font-weight: 750;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.md-typeset h1 {
|
||||
color: var(--cot-ink);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-typeset h1 {
|
||||
color: var(--md-default-fg-color);
|
||||
}
|
||||
|
||||
.md-typeset code {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.md-typeset pre > code {
|
||||
border-radius: 0.45rem;
|
||||
}
|
||||
|
||||
.md-typeset table:not([class]) {
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1220px) {
|
||||
.md-grid {
|
||||
max-width: 88rem;
|
||||
}
|
||||
}
|
||||
|
||||
.md-sidebar--primary {
|
||||
padding-left: 0.85rem;
|
||||
border-right: 1px solid rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
.md-sidebar--primary .md-sidebar__scrollwrap {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.md-sidebar--primary .md-logo {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.md-sidebar--secondary {
|
||||
color: #667085;
|
||||
}
|
||||
|
||||
.md-nav__title {
|
||||
color: #111827;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.md-nav__item .md-nav__link--active {
|
||||
color: var(--cot-blue);
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.md-nav--primary > .md-nav__list > .md-nav__item > .md-nav__link--active {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.md-nav--primary > .md-nav__list > .md-nav__item > .md-nav__link--active::before {
|
||||
position: absolute;
|
||||
top: 0.28rem;
|
||||
bottom: 0.28rem;
|
||||
left: -0.65rem;
|
||||
width: 2px;
|
||||
content: "";
|
||||
background: var(--cot-blue);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-sidebar--primary {
|
||||
border-right-color: rgba(148, 163, 184, 0.14);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-nav__title {
|
||||
color: #f8fafc;
|
||||
}
|
||||
|
||||
.md-sidebar--primary .md-nav--primary > .md-nav__list {
|
||||
padding-left: 0.7rem;
|
||||
border-left: 1px solid rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
.md-sidebar--primary .md-nav--primary .md-nav__title[for="__drawer"] {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
height: 6.8rem;
|
||||
padding: 0 0 1.25rem;
|
||||
margin: 0 0 0.7rem;
|
||||
overflow: hidden;
|
||||
color: #111827;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.md-sidebar--primary .md-nav--primary .md-nav__title[for="__drawer"] .md-logo {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.md-sidebar--primary .md-nav--primary .md-nav__title[for="__drawer"] .md-logo img,
|
||||
.md-sidebar--primary .md-nav--primary .md-nav__title[for="__drawer"] .md-logo svg {
|
||||
width: auto;
|
||||
max-width: 12.4rem;
|
||||
height: 1.72rem;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-sidebar--primary .md-nav--primary > .md-nav__list {
|
||||
border-left-color: rgba(148, 163, 184, 0.14);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-sidebar--primary .md-nav--primary .md-nav__title[for="__drawer"] {
|
||||
color: #f8fafc;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.home-hero {
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
margin-bottom: 3.6rem;
|
||||
padding: 3.25rem 1.5rem 3.8rem;
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
border-bottom: 1px solid rgba(15, 23, 42, 0.07);
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.home-hero::before {
|
||||
position: absolute;
|
||||
inset: 0 -7rem auto -7rem;
|
||||
z-index: -1;
|
||||
height: 20rem;
|
||||
pointer-events: none;
|
||||
content: "";
|
||||
background:
|
||||
linear-gradient(180deg, rgba(239, 246, 255, 0.78), rgba(255, 255, 255, 0) 88%),
|
||||
linear-gradient(115deg, transparent 0 30%, rgba(37, 99, 235, 0.06) 30% 42%, transparent 42%),
|
||||
linear-gradient(165deg, transparent 0 38%, rgba(37, 99, 235, 0.052) 38% 58%, transparent 58%),
|
||||
linear-gradient(90deg, rgba(148, 163, 184, 0.1) 1px, transparent 1px),
|
||||
linear-gradient(0deg, rgba(148, 163, 184, 0.1) 1px, transparent 1px);
|
||||
background-size: auto, auto, auto, 56px 56px, 56px 56px;
|
||||
mask-image: linear-gradient(to bottom, black, transparent 88%);
|
||||
}
|
||||
|
||||
.home-eyebrow {
|
||||
margin: 0;
|
||||
color: var(--cot-cyan);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 850;
|
||||
letter-spacing: 0.16em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.home-hero h1 {
|
||||
max-width: 34rem;
|
||||
margin: 0.9rem 0 0;
|
||||
color: var(--cot-ink);
|
||||
font-size: clamp(2rem, 3vw, 2.45rem);
|
||||
font-weight: 900;
|
||||
line-height: 1.12;
|
||||
}
|
||||
|
||||
.home-lede {
|
||||
max-width: 44rem;
|
||||
margin: 1rem 0 0;
|
||||
color: #5f6b7a;
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.home-link {
|
||||
display: inline-flex;
|
||||
margin-top: 1.25rem;
|
||||
color: var(--cot-cyan);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 850;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.home-link:hover {
|
||||
color: var(--cot-blue);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.md-footer {
|
||||
color: #667085;
|
||||
background: #fff;
|
||||
border-top: 1px solid rgba(15, 23, 42, 0.07);
|
||||
}
|
||||
|
||||
.md-footer-meta {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.md-footer__link {
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.md-footer__direction {
|
||||
color: #667085;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-footer,
|
||||
[data-md-color-scheme="slate"] .md-footer-meta {
|
||||
color: #cbd5e1;
|
||||
background: #0f172a;
|
||||
border-top-color: rgba(148, 163, 184, 0.14);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-footer__link {
|
||||
color: #f8fafc;
|
||||
}
|
||||
|
||||
.quickstart-grid,
|
||||
.resource-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 1.6rem;
|
||||
padding-top: 1.8rem;
|
||||
margin-top: 1rem;
|
||||
border-top: 1px solid rgba(15, 23, 42, 0.07);
|
||||
}
|
||||
|
||||
.quickstart-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 10.5rem;
|
||||
padding: 0.2rem 0;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 0.55rem;
|
||||
box-shadow: none;
|
||||
transition: color 180ms ease, transform 180ms ease;
|
||||
}
|
||||
|
||||
.quickstart-card:hover {
|
||||
text-decoration: none;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.quickstart-step {
|
||||
align-self: flex-start;
|
||||
padding: 0;
|
||||
margin-bottom: 0.75rem;
|
||||
color: var(--cot-blue);
|
||||
font-size: 0.68rem;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.quickstart-card strong,
|
||||
.resource-card strong {
|
||||
display: block;
|
||||
color: #111827;
|
||||
font-size: 0.86rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.quickstart-card span:not(.quickstart-step),
|
||||
.resource-card span:not(.resource-art) {
|
||||
display: block;
|
||||
margin-top: 0.55rem;
|
||||
color: #667085;
|
||||
font-size: 0.78rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.quickstart-card em {
|
||||
margin-top: auto;
|
||||
color: var(--cot-cyan);
|
||||
font-size: 0.76rem;
|
||||
font-style: normal;
|
||||
font-weight: 850;
|
||||
}
|
||||
|
||||
.quickstart-card:hover strong,
|
||||
.quickstart-card:hover em {
|
||||
color: var(--cot-blue-dark);
|
||||
}
|
||||
|
||||
.resource-card {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
background: #fff;
|
||||
border: 1px solid #dbe3ec;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
|
||||
transition: transform 180ms ease, box-shadow 180ms ease;
|
||||
}
|
||||
|
||||
.resource-card:hover {
|
||||
text-decoration: none;
|
||||
box-shadow: 0 18px 36px rgba(15, 23, 42, 0.1);
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
.resource-art {
|
||||
display: block;
|
||||
height: 5.6rem;
|
||||
padding: 1rem;
|
||||
background:
|
||||
linear-gradient(155deg, rgba(248, 250, 252, 1), rgba(239, 246, 255, 0.92)),
|
||||
linear-gradient(90deg, rgba(148, 163, 184, 0.16) 1px, transparent 1px),
|
||||
linear-gradient(0deg, rgba(148, 163, 184, 0.16) 1px, transparent 1px);
|
||||
background-size: auto, 48px 48px, 48px 48px;
|
||||
border-bottom: 1px solid #eef2f7;
|
||||
}
|
||||
|
||||
.resource-art b {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.2rem;
|
||||
height: 2.2rem;
|
||||
color: var(--cot-blue);
|
||||
font-size: 0.62rem;
|
||||
background: #fff;
|
||||
border: 1px solid #cbd5e1;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.resource-card > strong,
|
||||
.resource-card > span:not(.resource-art) {
|
||||
margin-right: 1.25rem;
|
||||
margin-left: 1.25rem;
|
||||
}
|
||||
|
||||
.resource-card > strong {
|
||||
margin-top: 1.25rem;
|
||||
}
|
||||
|
||||
.resource-card > span:not(.resource-art) {
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .home-hero {
|
||||
background: transparent;
|
||||
border-color: rgba(148, 163, 184, 0.14);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .home-hero::before {
|
||||
background:
|
||||
linear-gradient(180deg, rgba(30, 41, 59, 0.52), rgba(15, 23, 42, 0) 88%),
|
||||
linear-gradient(115deg, transparent 0 30%, rgba(96, 165, 250, 0.1) 30% 42%, transparent 42%),
|
||||
linear-gradient(90deg, rgba(148, 163, 184, 0.08) 1px, transparent 1px),
|
||||
linear-gradient(0deg, rgba(148, 163, 184, 0.08) 1px, transparent 1px);
|
||||
background-size: auto, auto, 56px 56px, 56px 56px;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .home-hero h1,
|
||||
[data-md-color-scheme="slate"] .quickstart-card strong,
|
||||
[data-md-color-scheme="slate"] .resource-card strong {
|
||||
color: #f8fafc;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .home-lede,
|
||||
[data-md-color-scheme="slate"] .quickstart-card span:not(.quickstart-step),
|
||||
[data-md-color-scheme="slate"] .resource-card span:not(.resource-art) {
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .quickstart-card,
|
||||
[data-md-color-scheme="slate"] .resource-card {
|
||||
background: transparent;
|
||||
border-color: rgba(148, 163, 184, 0.24);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .quickstart-card:hover,
|
||||
[data-md-color-scheme="slate"] .resource-card:hover {
|
||||
border-color: var(--cot-blue-bright);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .quickstart-step {
|
||||
color: #bfdbfe;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .resource-art {
|
||||
background:
|
||||
linear-gradient(155deg, rgba(15, 23, 42, 1), rgba(30, 41, 59, 0.82)),
|
||||
linear-gradient(90deg, rgba(148, 163, 184, 0.12) 1px, transparent 1px),
|
||||
linear-gradient(0deg, rgba(148, 163, 184, 0.12) 1px, transparent 1px);
|
||||
background-size: auto, 48px 48px, 48px 48px;
|
||||
border-bottom-color: rgba(148, 163, 184, 0.14);
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .resource-art b {
|
||||
color: #bfdbfe;
|
||||
background: #020617;
|
||||
border-color: rgba(148, 163, 184, 0.34);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 960px) {
|
||||
.quickstart-grid,
|
||||
.resource-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 82em) {
|
||||
.md-nav--primary .md-nav__title[for="__drawer"] {
|
||||
display: none;
|
||||
height: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.md-sidebar--primary {
|
||||
padding-left: 0;
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.md-sidebar--primary .md-nav--primary > .md-nav__list {
|
||||
padding-left: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
[data-md-color-scheme="slate"] .md-nav--primary .md-nav__title[for="__drawer"] {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 640px) {
|
||||
.home-hero {
|
||||
max-width: calc(100vw - 2rem);
|
||||
padding: 2.4rem 1rem 2.8rem;
|
||||
}
|
||||
|
||||
.home-hero::before {
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
.home-hero h1,
|
||||
.home-lede {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.quickstart-grid,
|
||||
.resource-grid {
|
||||
grid-template-columns: 1fr;
|
||||
max-width: calc(100vw - 2rem);
|
||||
}
|
||||
|
||||
.quickstart-card {
|
||||
min-height: auto;
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
site_name: Co-op Translator
|
||||
site_description: API and CLI documentation for Co-op Translator.
|
||||
site_url: https://azure.github.io/co-op-translator/
|
||||
repo_url: https://github.com/Azure/co-op-translator
|
||||
repo_name: Azure/co-op-translator
|
||||
|
||||
docs_dir: docs
|
||||
site_dir: site
|
||||
|
||||
theme:
|
||||
name: material
|
||||
language: en
|
||||
logo: assets/logo.png
|
||||
favicon: assets/logo.png
|
||||
icon:
|
||||
repo: fontawesome/brands/github
|
||||
features:
|
||||
- navigation.instant
|
||||
- navigation.sections
|
||||
- navigation.top
|
||||
- navigation.footer
|
||||
- search.highlight
|
||||
- search.suggest
|
||||
- content.code.copy
|
||||
- content.tabs.link
|
||||
palette:
|
||||
- scheme: default
|
||||
primary: blue
|
||||
accent: cyan
|
||||
toggle:
|
||||
icon: material/weather-night
|
||||
name: Switch to dark mode
|
||||
- scheme: slate
|
||||
primary: blue
|
||||
accent: cyan
|
||||
toggle:
|
||||
icon: material/weather-sunny
|
||||
name: Switch to light mode
|
||||
|
||||
extra_css:
|
||||
- stylesheets/extra.css
|
||||
|
||||
extra_javascript:
|
||||
- javascripts/tailwind-config.js
|
||||
- https://cdn.tailwindcss.com
|
||||
|
||||
plugins:
|
||||
- search
|
||||
- mkdocstrings:
|
||||
handlers:
|
||||
python:
|
||||
paths:
|
||||
- src
|
||||
options:
|
||||
docstring_style: google
|
||||
show_source: false
|
||||
show_root_heading: true
|
||||
show_signature_annotations: true
|
||||
separate_signature: true
|
||||
|
||||
markdown_extensions:
|
||||
- admonition
|
||||
- attr_list
|
||||
- def_list
|
||||
- md_in_html
|
||||
- toc:
|
||||
permalink: true
|
||||
- pymdownx.details
|
||||
- pymdownx.highlight:
|
||||
anchor_linenums: true
|
||||
- pymdownx.superfences
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- pymdownx.emoji:
|
||||
emoji_index: !!python/name:material.extensions.emoji.twemoji
|
||||
emoji_generator: !!python/name:material.extensions.emoji.to_svg
|
||||
|
||||
nav:
|
||||
- Home: index.md
|
||||
- Configuration: configuration.md
|
||||
- Examples: examples.md
|
||||
- Python API: api.md
|
||||
- CLI Reference: cli.md
|
||||
- Maintainer Guide: maintainer-guide.md
|
||||
@@ -0,0 +1,3 @@
|
||||
mkdocs>=1.6,<2.0
|
||||
mkdocs-material>=9.5,<9.6
|
||||
mkdocstrings[python]>=0.27,<1.0
|
||||
Reference in New Issue
Block a user