Μετάβαση στο περιεχόμενο

Εξαγωγή

Η εξαγωγή είναι το βήμα που συλλέγει κάθε επισημασμένο μήνυμα από τον πηγαίο κώδικά σας σε ένα πρότυπο .pot για τους μεταφραστές — το βήμα 3 του βρόχου της εκμάθησης. Αυτή η σελίδα είναι η αναφορά για εκείνο το βήμα: ρύθμιση, προσαρμοσμένα ονόματα συναρτήσεων, αυστηρή λειτουργία για CI, και οι έλεγχοι που φρουρούν έπειτα τους καταλόγους σας.

Η εξαγωγή χρειάζεται το extra babel:

python -m pip install "gettext-tstrings[babel]"

Η ροή εργασίας

Δημιουργήστε το babel.cfg:

[gettext_tstrings: **.py]
encoding = utf-8

Έπειτα χρησιμοποιήστε τις συνηθισμένες εντολές του Babel:

pybabel extract -F babel.cfg -c "Translators:" -o locales/messages.pot .
pybabel init -i locales/messages.pot -d locales -l ja
pybabel compile -d locales

Το init τρέχει μία φορά ανά γλώσσα· από εκεί και πέρα, το pybabel update ενσωματώνει κάθε φρέσκο πρότυπο στους υπάρχοντες καταλόγους. Αυτός ο επαναλαμβανόμενος κύκλος — και τι σημαίνουν οι καταχωρίσεις του fuzzy για μια έκδοση — αναλύεται στο Στην παραγωγή.

Ο εξαγωγέας gettext_tstrings χειρίζεται επίσης συνηθισμένες κλήσεις _(), gettext() και ngettext(), ώστε μία αντιστοίχιση να καλύπτει μια μεικτή βάση κώδικα. Αναγνωρίζει την _(), τα τέσσερα τυπικά ονόματα gettext, τα ψευδώνυμα tr() / ntr(), και τις αναβαλλόμενες lazy_gettext() / lazy_pgettext().

Ενεργοποιήστε τα σχόλια για μεταφραστές με -c

Το pybabel extract συλλέγει σχόλια για μεταφραστές μόνο όταν περάσετε -c "Translators:", ακριβώς όπως κάνει και για τις συνηθισμένες κλήσεις gettext. Αν το παραλείψετε, η εξαγωγή εξακολουθεί να λειτουργεί — απλώς τα σχόλια δεν φτάνουν ποτέ στον κατάλογο, όπου είναι ο φθηνότερος μοχλός ποιότητας ολόκληρης της ροής εργασίας.

Καταχώριση των δικών σας ονομάτων συναρτήσεων

[gettext_tstrings: **.py]
tr_functions = tr translate
ntr_functions = ntr
[[mappings]]
method = "gettext_tstrings"
pattern = "**.py"
tr_functions = ["tr", "translate"]
ntr_functions = ["ntr"]

Ένα αρχείο ini δίνει μία συμβολοσειρά, μια αντιστοίχιση TOML δίνει μια λίστα, και μέσα σε μια συμβολοσειρά τα ονόματα χωρίζονται είτε με κενά είτε με κόμματα. Και οι τέσσερις γραφές λειτουργούν.

Οι επιλογές είναι tr_functions, ntr_functions, gettext_functions, ngettext_functions, pgettext_functions και npgettext_functions.

Το -k δεν φτάνει σε ένα t-string

Ένας προσαρμοσμένος βοηθός όπως η mytr(t"…") πρέπει να κατονομαστεί σε μία από τις παραπάνω επιλογές. Ο μηχανισμός --keyword του Babel δεν μπορεί να διαβάσει ένα literal t-string, οπότε το pybabel extract -k mytr δεν βρίσκει τίποτα και δεν λέει τίποτα — τα μηνύματα απλώς απουσιάζουν από το POT. Το -k συνεχίζει να λειτουργεί για τις συνηθισμένες κλήσεις gettext που εξάγονται παράλληλα.

Υποστηρίζεται μόνο η τυπική σειρά ορισμάτων: πρώτα το μήνυμα, συγκείμενο και μετά μήνυμα για την pgettext, συγκείμενο, μετά ενικός, μετά πληθυντικός για την npgettext.

Επιεικές τοπικά, αυστηρό στο CI

Από προεπιλογή, ένα κακό αρχείο δεν τερματίζει την εκτέλεση:

  • Ένα t-string που ο εξαγωγέας απορρίπτει — πρόσβαση σε ιδιότητα, έκφραση, λάθος όρισμα — αναφέρεται ως προειδοποίηση και παραλείπεται.
  • Ένα αρχείο που δεν αναλύεται συντακτικά παραλείπεται με τον ίδιο τρόπο.
  • Το ίδιο και ένα αρχείο που μόνο το tokenize αρνείται ενώ το ast το δέχεται — ένα αρχείο στο οποίο το πέρασμα του ίδιου του Babel αλλιώς θα διακοπτόταν.

Αυτό είναι βολικό όσο επεξεργάζεστε τον κώδικα και επικίνδυνο όταν δεν τον επεξεργάζεστε: ένα μήνυμα που παραλείπεται απλώς απουσιάζει από το POT, οπότε δεν μεταφράζεται ποτέ και τίποτα δεν το λέει. Ορίστε strict = true στις επιλογές της αντιστοίχισης όπου η εξαγωγή δεν παρακολουθείται από άνθρωπο:

[gettext_tstrings: **.py]
encoding = utf-8
strict = true
[[mappings]]
method = "gettext_tstrings"
pattern = "**.py"
strict = true

Κάθε προειδοποίηση από τις παραπάνω γίνεται τότε σκληρή αποτυχία. Αντιμετωπίστε αυτή τη ρύθμιση ως τη ρύθμιση παραγωγής και την προεπιλογή ως την τοπική.

Η υπάρχουσα εργαλειοθήκη σας επικυρώνει αυτούς τους καταλόγους

Το Babel σημειώνει κάθε εξαγόμενο μήνυμα με μια τυπική σημαία, και αυτή η μία γραμμή είναι που ενεργοποιεί τον έλεγχο συμβόλων κράτησης θέσης στα εργαλεία που ήδη τρέχετε:

#. gettext-tstrings
#: app.py:4
#, python-brace-format
msgid "Hello {name}"
msgstr ""

Μεταφράστε το ως こんにちは {nombre} και το λάθος πιάνεται χωρίς καμία ρύθμιση:

$ msgfmt --check-format -o /dev/null locales/ja/LC_MESSAGES/messages.po
locales/ja/LC_MESSAGES/messages.po:25: a format specification for argument
'name' doesn't exist in 'msgstr'
msgfmt: found 1 fatal error

Το Weblate τεκμηριώνει τον ίδιο έλεγχο ως Python brace format, και οι εμπορικές πλατφόρμες έχουν το δικό τους QA συμβόλων κράτησης θέσης δεμένο στην ίδια σημαία. Η συμπεριφορά κάθε πλατφόρμας είναι δική της υπόθεση· τα δύο εργαλεία παρακάτω είναι αυτά που έχουν επαληθευτεί εδώ.

Επιπλέον, το πακέτο καταχωρίζει έναν ελεγκτή (checker) στο Babel, οπότε το pybabel compile εφαρμόζει τους κανόνες της προδιαγραφής σε κάθε μήνυμα που φέρει το σχόλιο-δείκτη gettext-tstrings:

$ pybabel compile -d locales -l ja
error: locales/ja/LC_MESSAGES/messages.po:24: translation does not match the
source placeholders: {name} is missing; {nombre} is not in the source message
1 errors encountered.

Για ένα μήνυμα πληθυντικού ο δείκτης κατονομάζει τη μορφή, γιατί ο αριθμός γραμμής που αναφέρει το Babel είναι του msgid και ένα ρωσικό μπλοκ έχει τρία msgstr από κάτω του:

error: locales/ru/LC_MESSAGES/messages.po:31: msgstr[1]: translation does not
match the source placeholders: {n} is missing

Το pybabel compile γράφει παρ' όλα αυτά το .mo

Το παραπάνω σφάλμα αναφέρεται, ο κωδικός εξόδου είναι 1 — και ο χαλασμένος κατάλογος μεταγλωττίζεται ούτως ή άλλως. Μόνο αυτός ο κωδικός εξόδου μπορεί να εμποδίσει μια γραμμή παραγωγής να τον στείλει· το Τι φρουρεί το CI δείχνει το βήμα build που το επιτρέπει.

Οι δύο έλεγχοι δεν είναι πλεονασμός. Ο ελεγκτής του πακέτου είναι αυστηρότερος σε τουλάχιστον δύο περιπτώσεις:

  • Ένα msgid του οποίου τα μόνα άγκιστρα είναι με διαφυγή (Config {{raw}} only) δεν παίρνει ποτέ τη σημαία python-brace-format, οπότε κανένα εξωτερικό εργαλείο δεν το επικυρώνει καθόλου.
  • Οι μορφές πληθυντικού ελέγχονται μία προς μία. Το msgfmt --check-format διαβάζει το ίδιο ακριβώς αρχείο παραπάνω και τερματίζει με 0· μια μορφή που παραλείπει ένα σύμβολο κράτησης θέσης που κρατούν οι αδελφές της γίνεται δεκτή εκεί και απορρίπτεται εδώ.

Το msgfmt ελέγχει μόνο ονόματα συμβόλων κράτησης θέσης που μπορεί να αναλύσει ως Python brace format, οπότε τα ονόματα ASCII κρατούν κάθε εργαλείο της αλυσίδας ικανό να επικυρώσει το μήνυμα. Η ίδια η βιβλιοθήκη δέχεται οποιοδήποτε όνομα ικανοποιεί το str.isidentifier().

Πρότυπα και άλλα εργαλεία

Τα t-strings είναι σύνταξη Python, οπότε αυτή η βιβλιοθήκη καλύπτει πηγαίο κώδικα Python. Οι γλώσσες προτύπων συνεχίζουν να χρησιμοποιούν το δικό τους i18n — το {% trans %} του Jinja2, τις ετικέτες προτύπων του Django — και τους εξαγωγείς του Babel για αυτές. Όλα τροφοδοτούν τον ίδιο κατάλογο PO, οπότε μία ροή εργασίας μετάφρασης εξακολουθεί να καλύπτει μια μεικτή βάση κώδικα.

Το pygettext δεν μπορεί σήμερα να αναλύσει t-strings, γι' αυτό η εξαγωγή περνά μέσα από το Babel. Η σύμβαση είναι καταγεγραμμένη στην προδιαγραφή ώστε ένας άλλος εξαγωγέας, ή ένα μελλοντικό pygettext, να μπορεί να τη στοχεύσει.