Translate all fulltext files in a section (e.g. nmpa/guidance).
(section: str, limit: int = 0, dry_run: bool = False,
force: bool = False)
| 240 | |
| 241 | |
| 242 | def process_section(section: str, limit: int = 0, dry_run: bool = False, |
| 243 | force: bool = False): |
| 244 | """Translate all fulltext files in a section (e.g. nmpa/guidance).""" |
| 245 | parts = section.split('/') |
| 246 | if len(parts) != 2: |
| 247 | logger.error(f"Section must be framework/type (e.g. nmpa/guidance)") |
| 248 | return |
| 249 | |
| 250 | framework, doc_type = parts |
| 251 | fulltext_dir = KNOWLEDGE_ROOT / framework / doc_type / "fulltext" |
| 252 | |
| 253 | if not fulltext_dir.exists(): |
| 254 | logger.error(f"Directory not found: {fulltext_dir}") |
| 255 | return |
| 256 | |
| 257 | zh_files = sorted(fulltext_dir.glob("*.md")) |
| 258 | zh_files = [f for f in zh_files if not f.stem.endswith('.en')] |
| 259 | |
| 260 | candidates = [] |
| 261 | already_done = 0 |
| 262 | for zh_path in zh_files: |
| 263 | en_path = get_en_path(zh_path) |
| 264 | if not force and en_path.exists(): |
| 265 | already_done += 1 |
| 266 | continue |
| 267 | candidates.append(zh_path) |
| 268 | |
| 269 | total_candidates = len(candidates) |
| 270 | if limit > 0: |
| 271 | candidates = candidates[:limit] |
| 272 | |
| 273 | logger.info(f"Translating {len(candidates)} files from {fulltext_dir}") |
| 274 | logger.info(f" Total ZH files: {len(zh_files)}, " |
| 275 | f"Already translated: {already_done}, " |
| 276 | f"Remaining: {total_candidates}") |
| 277 | |
| 278 | success = 0 |
| 279 | failed = 0 |
| 280 | |
| 281 | for i, zh_path in enumerate(candidates): |
| 282 | logger.info(f"[{i+1}/{len(candidates)}] {zh_path.name}") |
| 283 | |
| 284 | if dry_run: |
| 285 | continue |
| 286 | |
| 287 | en_text = translate_document(zh_path) |
| 288 | if not en_text: |
| 289 | failed += 1 |
| 290 | continue |
| 291 | |
| 292 | en_path = get_en_path(zh_path) |
| 293 | en_path.write_text(en_text, encoding="utf-8") |
| 294 | logger.info(f" Saved: {en_path.name} ({len(en_text)} chars)") |
| 295 | success += 1 |
| 296 | |
| 297 | logger.info(f"\nTranslation complete: {success} succeeded, {failed} failed") |
| 298 | |
| 299 |
no test coverage detected