Skip to content

Commit ee1dfb0

Browse files
committed
docs(l10n): add AI agent instructions for translating po/XX.po files
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
1 parent 1025d14 commit ee1dfb0

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

po/README.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,118 @@ The command will handle all necessary steps including generating
495495
"po/git.pot" and merging new translatable strings into "po/XX.po"
496496
automatically.
497497

498+
### Translating po/XX.po
499+
500+
When asked to translate "po/XX.po" or similar requests:
501+
502+
**IMPORTANT: You must complete the translation of ALL untranslated and fuzzy
503+
entries. Do not stop early or report partial progress. Continue iterating
504+
through steps 1-6 until `po/XX.po.pending` is empty (contains no entries).**
505+
506+
1. **Extract entries to translate**: Use `msgattrib` to extract
507+
untranslated and fuzzy messages separately, then combine them. The
508+
`--clear-fuzzy --empty` options for fuzzy entries clear their `msgstr`
509+
values, treating them as untranslated entries:
510+
511+
```shell
512+
msgattrib --untranslated --no-obsolete po/XX.po -o po/XX.po.untranslated
513+
msgattrib --only-fuzzy --no-obsolete --clear-fuzzy --empty po/XX.po -o po/XX.po.fuzzy
514+
msgcat --use-first po/XX.po.untranslated po/XX.po.fuzzy -o po/XX.po.pending
515+
```
516+
517+
If `po/XX.po.pending` is empty, skip to step 7 (clean up) as the
518+
translation is complete.
519+
520+
2. **Truncate large po/XX.po.pending file**: If the `po/XX.po.pending` file
521+
is too large to load at once, truncate it to process in batches:
522+
523+
2.1. **Find msgid line numbers**: Locate all `msgid` entry positions in
524+
the file:
525+
526+
```shell
527+
grep -n "^msgid " po/XX.po.pending > msgid_lines.txt
528+
```
529+
530+
2.2. **Count total entries**: Check how many entries exist:
531+
532+
```shell
533+
TOTAL_ENTRIES=$(wc -l < msgid_lines.txt)
534+
echo "Total entries: $TOTAL_ENTRIES"
535+
```
536+
537+
2.3. **Determine truncation point**: Find the line number immediately
538+
before the 201st `msgid` entry (to keep the first 200 entries):
539+
540+
```shell
541+
# Get the line number of the 201st msgid
542+
SPLIT_LINE=$(sed -n '201p' msgid_lines.txt | cut -d: -f1)
543+
# Subtract 1 to cut before this msgid
544+
SPLIT_LINE=$((SPLIT_LINE - 1))
545+
```
546+
547+
2.4. **Truncate the file**: Keep only the first 200 entries by truncating
548+
at the determined line:
549+
550+
```shell
551+
head -n $SPLIT_LINE po/XX.po.pending > po/XX.po.pending.tmp
552+
mv po/XX.po.pending.tmp po/XX.po.pending
553+
```
554+
555+
2.5. **If still too large**: If the truncated file is still too large,
556+
use smaller batch sizes (try 100 entries, then 50, and so on):
557+
558+
```shell
559+
# For 100 entries
560+
SPLIT_LINE=$(sed -n '101p' msgid_lines.txt | cut -d: -f1)
561+
SPLIT_LINE=$((SPLIT_LINE - 1))
562+
head -n $SPLIT_LINE po/XX.po.pending > po/XX.po.pending.tmp
563+
mv po/XX.po.pending.tmp po/XX.po.pending
564+
```
565+
566+
3. **Reference glossary**: Read the glossary section from the header of
567+
`po/XX.po` (if present, before the first `msgid`) and use it for
568+
consistent terminology during translation.
569+
570+
4. **Translate entries**: Translate entries in `po/XX.po.pending` from English
571+
(msgid) to the target language (msgstr), and write the translation results
572+
directly into `po/XX.po.pending`:
573+
- **Translation approach**: Translate the `po/XX.po.pending` file as a
574+
whole, rather than translating entry by entry. If the file was truncated
575+
in step 2, translate the current batch completely. **You must translate
576+
ALL entries in the current batch** - do not stop after translating only
577+
part of the batch.
578+
- **For untranslated entries**: Translate the English `msgid` into the
579+
target language in `msgstr`.
580+
- **For fuzzy entries**: Since fuzzy entries have been cleared (empty
581+
`msgstr`) in step 1, treat them the same as untranslated entries:
582+
translate the English `msgid` into the target language in `msgstr`.
583+
The `#, fuzzy` tag will be automatically removed when the entry is
584+
merged back into `po/XX.po`.
585+
- **For plural entries**: For entries with `msgid_plural`, provide all
586+
required `msgstr[n]` forms based on the `Plural-Forms` header in
587+
`po/XX.po`. The number of plural forms required depends on the target
588+
language's plural rules.
589+
590+
5. **Merge translated entries**: Merge the translated `po/XX.po.pending`
591+
back into `po/XX.po`:
592+
593+
```shell
594+
msgcat --use-first po/XX.po.pending po/XX.po > po/XX.po.merged
595+
mv po/XX.po.merged po/XX.po
596+
```
597+
598+
6. **Repeat until complete**: **MANDATORY**: You MUST repeat steps 1-5
599+
(extract, truncate if needed, translate, merge) until `po/XX.po.pending`
600+
is completely empty. Do not report partial progress or stop early. The
601+
task is only complete when there are zero untranslated and zero fuzzy
602+
entries remaining in `po/XX.po`.
603+
604+
7. **Clean up**: Only after confirming that `po/XX.po.pending` is empty
605+
(no untranslated or fuzzy entries remain), remove all temporary files
606+
(`po/XX.po.pending`, `po/XX.po.untranslated`, `po/XX.po.fuzzy`,
607+
`msgid_lines.txt` if created). Do not clean up if there are still
608+
untranslated or fuzzy entries remaining.
609+
498610

499611
[git-po-helper/README]: https://github.com/git-l10n/git-po-helper#readme
500612
[Documentation/SubmittingPatches]: Documentation/SubmittingPatches

0 commit comments

Comments
 (0)