Παγίδες¶
Αυτός ο ιστότοπος είναι μεταφρασμένος σε τριάντα πέντε γλώσσες, και καθεμία από αυτές παρήχθη τρέχοντας τον βρόχο που διδάσκει αυτή η τεκμηρίωση. Με τα μέτρα του κλάδου πρόκειται για μικρό σώμα κειμένων, και παρ' όλα αυτά αρκούσε για να πέσουμε στις περισσότερες από τις παγίδες που κάνουν το i18n δυσκολότερο απ' ό,τι φαίνεται.
Κάθε ενότητα παρακάτω είναι κάτι που πήγε πραγματικά στραβά εδώ, πώς έμοιαζε τότε, και πού περνά η γραμμή ανάμεσα σε αυτό που ελέγχει η βιβλιοθήκη για εσάς και σε αυτό που παραμένει δική σας κρίση.
Η μετονομασία μιας μεταβλητής ξαναμεταφράζει μια πρόταση¶
Το msgid είναι το κλειδί του καταλόγου, και ένα παρεμβαλλόμενο όνομα βρίσκεται
μέσα του. Η μετακίνηση μιας σταθεράς στο επίπεδο του αρθρώματος και η γραφή
της με κεφαλαία, όπως ζητά το στιλ της Python — από author σε AUTHOR —
μετέτρεψε το Copyright © 2026 {author} · MIT License σε μήνυμα που κανένας
κατάλογος δεν είχε ξαναδεί. Κάθε μετάφραση εκείνης της γραμμής θα περνούσε
ξανά μέσα από τον κύκλο του fuzzy, σε κάθε γλώσσα, για μια μετονομασία που δεν
άλλαζε τίποτα ορατό σε αναγνώστη.
Η βιβλιοθήκη δεν θα σας σταματήσει: και οι δύο γραφές είναι έγκυρα ονόματα συμβόλων κράτησης θέσης. Αυτό που κάνει είναι να κάνει το όνομα ν' αξίζει προστασία — μια παρεμβολή πρέπει να είναι απλό όνομα, οπότε αυτό που βρίσκεται στο κλειδί του καταλόγου είναι μια λέξη που μπορεί να διαβάσει ένας μεταφραστής, όχι μια έκφραση.
Η κατοπτρική περίπτωση είναι ασφαλής εκ κατασκευής. Οι μετατροπές και οι
προδιαγραφές μορφοποίησης δεν είναι μέρος του msgid, οπότε το σφίξιμο του
{amount:,.2f} σε {amount:,.0f} δεν αλλάζει κανένα κλειδί και δεν ακυρώνει
καμία μετάφραση πουθενά.
Το nplurals=2 δεν σημαίνει δύο διαφορετικές συμβολοσειρές¶
Τα τουρκικά, τα ουγγρικά, τα περσικά και τα βεγγαλικά δηλώνουν όλα δύο μορφές
πληθυντικού, και στις τέσσερις οι δύο μορφές ενός μηνύματος με πλήθος είναι
νομίμως η ίδια συμβολοσειρά — το ουσιαστικό μένει στον ενικό μετά από
αριθμητικό, οπότε το {n} sayfa είναι σωστό και για μία σελίδα και για δέκα.
Ένας αναθεωρητής που «διορθώνει» την επανάληψη χαλάει τη μετάφραση.
Το αντίστροφο λάθος είναι εξίσου εύκολο. Η τρίτη μορφή των λετονικών υπάρχει
για το μηδέν και μόνο· η δεύτερη των σλοβενικών είναι δυϊκός, για
ακριβώς δύο· η τελευταία μορφή των ρουμανικών απαιτεί τη λέξη de, την οποία
οι δύο πρώτες δεν πρέπει να έχουν. Το γέμισμα αυτών των θέσεων με έναν ενικό
και έναν πληθυντικό παράγει κατάλογο που είναι λανθασμένος μόνο για πλήθη που
κανείς δεν δοκιμάζει.
Χειρότερα, η σειρά των θέσεων δεν είναι σημασιολογική. Τα ουαλικά
ευρετηριάζουν τις πέντε μορφές τους έτσι ώστε το msgstr[0] να είναι η γενική
περίπτωση και το msgstr[1] ο ενικός. Το γέμισμά τους με την προφανή σειρά
βάζει τον ενικό ακριβώς εκεί όπου θα τον βρει κάθε μήνυμα χωρίς πλήθος.
Η βιβλιοθήκη δεν αναλαμβάνει τίποτα από αυτά, και αυτό ακριβώς είναι το ζητούμενο: ο κανόνας πληθυντικού της γλώσσας-στόχου ζει στην κεφαλίδα του δικού της καταλόγου, και ο κανόνας ένωσης/τομής επιτρέπει σε μια μετάφραση να έχει περισσότερες μορφές, ή λιγότερες, από την πηγή. Αυτό που ελέγχει είναι το μόνο που μπορεί να ελέγξει χωρίς να γνωρίζει τη γλώσσα — ότι κάθε μορφή διατηρεί τα σύμβολα κράτησης θέσης που χρειάζεται.
Δύο μορφές μπορεί να ταυτίζονται για κάποιον λόγο¶
Τα ιρλανδικά έχουν πέντε μορφές πληθυντικού, και στην αναφορά build αυτού του
ιστότοπου αρκετές από αυτές γράφονται ίδια. Δεν πρόκειται για αβλεψία
αντιγραφής-επικόλλησης: το leathanach αρχίζει από l, και καμία από τις δύο
αρχικές μεταλλάξεις που πυροδοτούν τα ιρλανδικά αριθμητικά δεν γράφεται πάνω
στο l. Οι μορφές εξακολουθούν να κάνουν πραγματική δουλειά — το θέμα
εναλλάσσεται ανάμεσα σε leathanach και leathanaigh, και τα πλήθη πάνω από
το δέκα επιστρέφουν στον ενικό — αλλά κανένα ουσιαστικό με σημασία «σελίδα»
δεν θα έδειχνε την αντίθεση.
Οποιοσδήποτε έλεγχος σημαίνει ως ύποπτες τις διπλότυπες μορφές θα σημάνει και σωστά ιρλανδικά. Ένας άνθρωπος που ξέρει τη γλώσσα είναι ο μόνος αναθεωρητής γι' αυτό.
Ένα μήνυμα μπορεί να συμφωνεί με ένα μόνο πλήθος¶
Η αναφορά build αυτού του ιστότοπου λέει πόσες σελίδες αποδόθηκαν και πόσο
χρόνο πήρε. Το να γραφτεί ως "Rendered {n} pages in {seconds} seconds" μοιάζει
αθώο και δεν είναι μεταφράσιμο: το gettext επιλέγει μία μορφή από ένα πλήθος,
και αυτό το πλήθος είναι το n. Η λέξη seconds θα έπρεπε να συμφωνήσει με
έναν αριθμό που ο μηχανισμός του πληθυντικού δεν βλέπει ποτέ.
Η λύση είναι να γίνει η δεύτερη ποσότητα σύμβολο μονάδας αντί για λέξη, και τα
σύμβολα μονάδων είναι και αυτά τοπικοποιημένα: οι κατάλογοι αυτού του
ιστότοπου φέρουν s, с, ث, שנ׳ και mp, ενώ η γαλλική, η ισπανική και
η σουηδική τυπογραφία θέλουν διάστημα πριν από το σύμβολο εκεί όπου τα αγγλικά
δεν το βάζουν. Τίποτα από αυτά δεν είναι δουλειά της βιβλιοθήκης — αλλά το να
αντιληφθεί κανείς ότι ένα μήνυμα χρειάζεται δύο συμφωνίες είναι, και το μόνο
εργαλείο γι' αυτό είναι να γραφτεί το μήνυμα αλλιώς.
Η επεξεργασία μιας αγγλικής πρότασης επεξεργάζεται ξένη γραμματική¶
Η αρχική σελίδα έλεγε κάποτε "all ten language editions". Η αφαίρεση του αριθμού — μια αγγλική επεξεργασία μίας λέξης, που έγινε επειδή ο αριθμός συνεχώς ξεπερνιόταν — έκανε ενικό ένα πληθυντικό υποκείμενο. Τα ισπανικά, τα ιταλικά, τα πορτογαλικά, τα ρωσικά, τα ουκρανικά, τα ελληνικά, τα ολλανδικά και τα εβραϊκά χρειάστηκε όλα να ξανασυμφωνήσουν το ρήμα· αρκετά χρειάστηκαν και αλλαγή της μετοχής.
Μια επεξεργασία της πηγής που διαβάζεται ως ασήμαντη στα αγγλικά δεν είναι
ασήμαντη παρακάτω στη ροή. Η σήμανσή της ως fuzzy, που είναι ό,τι κάνει το
pybabel update, είναι ο μηχανισμός που δίνει σε κάθε μεταφραστή την ευκαιρία
να το προσέξει.
Οι αόρατες διαφορές επιβιώνουν από κάθε αντιγραφή-επικόλληση¶
Ο οδηγός παραθέτει ένα διαγνωστικό που περιέχει (nаme) — μια σκόπιμη
διαφυγή, γιατί ο χαρακτήρας που ονομάζει είναι ένα κυριλλικό а που κανένας
αναγνώστης δεν μπορεί να ξεχωρίσει από το λατινικό. Οι μεταφραστές αυτού του
ιστότοπου μετέτρεψαν αυτή τη διαφυγή στον πραγματικό χαρακτήρα πέντε
ξεχωριστές φορές, σε πέντε διαφορετικές γλώσσες, παράγοντας κάθε φορά μια
σελίδα που έμοιαζε σωστή και ήταν λανθασμένη.
Αυτό η βιβλιοθήκη το πιάνει, και είναι ο λόγος που τα διαγνωστικά έχουν τη μορφή που έχουν: ένα σύμβολο κράτησης θέσης του οποίου τα γράμματα αναμειγνύουν συστήματα γραφής αναφέρεται δύο φορές, μία ευανάγνωστα και μία με διαφυγή, γιατί η μορφή με διαφυγή είναι η μόνη γραφή που τα ξεχωρίζει. Ένα διάστημα χωρίς αλλαγή γραμμής μέσα σε άγκιστρα τυπώνεται κατά σημείο κώδικα για τον ίδιο λόγο. Ο ελεγκτής καταλόγων απορρίπτει το μήνυμα προτού προλάβει να διανεμηθεί.
Το μη κενό δεν σημαίνει μεταφρασμένο¶
Ένας κατάλογος που στήθηκε με τα msgid του αντιγραμμένα μέσα στα msgstr περνά κάθε αφελή έλεγχο: τίποτα δεν είναι κενό, τίποτα δεν είναι fuzzy, το σύνολο των μηνυμάτων ταιριάζει ακριβώς. Μια έκδοση αυτού του ιστότοπου κυκλοφόρησε έτσι για αρκετές ώρες. Το ίδιο και οκτώ σελίδες μιας άλλης έκδοσης που ήταν αντίγραφα της αγγλικής πηγής byte προς byte — πράγμα που περνά έναν έλεγχο ο οποίος συγκρίνει τα μπλοκ κώδικα μεταξύ τους, επειδή είναι το ίδιο αρχείο.
Κανένα από τα δύο δεν είναι κάτι που μπορεί να δει μια βιβλιοθήκη μετάφρασης.
Και τα δύο ελέγχονται φθηνά, αλλά όχι απαιτώντας να διαφέρει κάθε καταχώριση
από την πηγή της: το OK, τα ονόματα προϊόντων, τα ονόματα προσώπων, τα
αρκτικόλεξα και τα αναγνωριστικά κώδικα μεταφράζονται όλα στον εαυτό τους, και
ένας έλεγχος που το απαγορεύει παράγει ψευδώς θετικά για πάντα.
Μετρήστε αντ' αυτού το ποσοστό, σε ολόκληρο κατάλογο ή σε ολόκληρη σελίδα, και στείλτε τις ακραίες τιμές σε έναν άνθρωπο. Η δοκιμή αυτού του ιστότοπου κάνει ακριβώς αυτό: συγκρίνει τις γραμμές πεζού κειμένου κάθε έκδοσης με την αγγλική πηγή και αποτυγχάνει πάνω από 25% ταυτόσημες. Η πλαστή έκδοση βρισκόταν στο 87%· κάθε γνήσια μετάφραση βρίσκεται μεταξύ 4% και 8%, που είναι η μικρή ουρά γραμμών οι οποίες νόμιμα συμπίπτουν, όπως URL και παρατιθέμενη έξοδος προγράμματος. Οι δύο πληθυσμοί απέχουν αρκετά ώστε το κατώφλι να μη χρειάζεται να είναι ακριβές.
Ο κατάλογος δεν είναι το μόνο μεταφρασμένο πράγμα¶
Δύο αστοχίες εδώ δεν είχαν καμία σχέση με το gettext.
Η μετάφραση μιας επικεφαλίδας αλλάζει την άγκυρα που παράγεται από αυτήν, οπότε κάθε σύνδεσμος από άλλη σελίδα προς εκείνη την ενότητα σπάει — αθόρυβα, και μόνο σε εκείνη τη γλώσσα. Αυτός ο ιστότοπος καρφιτσώνει την αγγλική άγκυρα σε κάθε επικεφαλίδα, και μια δοκιμή παράγει την αναμενόμενη λίστα από την αγγλική σελίδα.
Και η γεννήτρια του ιστότοπου διαθέτει μεταφράσεις διεπαφής για εξήντα οκτώ γλώσσες, στις οποίες δεν περιλαμβάνονται τα σουαχίλι και τα ιρλανδικά. Χωρίς κάποια από αυτές το build δεν υποβαθμίζεται στα αγγλικά· το include του προτύπου αποτυγχάνει και η έκδοση δεν μπορεί να κατασκευαστεί καθόλου. Δύο αρχεία αυτού του ίδιου αποθετηρίου υπάρχουν για να καλύψουν αυτό το κενό.
Και τα εργαλεία σας έχουν σφάλματα¶
Το βήμα CI που συνιστά αυτή η τεκμηρίωση για τον εντοπισμό ξεπερασμένων
καταλόγων, το pybabel update --check, δεν μπορεί να κάνει αυτή τη δουλειά
για κανένα έργο που χρησιμοποιεί pgettext ή npgettext. Στο Babel 2.18.0
αναφέρει κάθε κατάλογο με msgctxt ως ξεπερασμένο, σε κάθε εκτέλεση. Η
σύγκριση περνά μέσα από την Catalog.is_identical, η οποία αναζητά κάθε
μήνυμα με το κλειδί υπό το οποίο είναι αποθηκευμένο — και για ένα μήνυμα με
συγκείμενο το κλειδί αυτό είναι το ζεύγος (id, context), που η Catalog.get
δεν δέχεται. Η αναζήτηση δεν επιστρέφει τίποτα, και οι κατάλογοι δεν
συγκρίνονται ποτέ ίσοι:
>>> from babel.messages.catalog import Catalog
>>> c = Catalog(locale="ja")
>>> c.add("Guide", "ガイド", context="navigation")
<Message 'Guide' (flags: [])>
>>> c.is_identical(c)
False
Βρέθηκε εδώ με την προσπάθεια χρήσης του, αναφέρθηκε upstream, και ο έλεγχος που το αντικαθιστά βρίσκεται στη σελίδα της παραγωγής.
Το γενικό δίδαγμα είναι το δυσάρεστο: μια πύλη που είναι πάντα κόκκινη είναι χειρότερη από καμία πύλη, γιατί μια ομάδα την απενεργοποιεί. Επαληθεύστε ότι ο έλεγχος CI σας μπορεί όντως να περάσει, προτού τον εμπιστευτείτε να αποτύχει.
Σε τι χρησιμεύει η βιβλιοθήκη, σε μία γραμμή¶
Το μεγαλύτερο μέρος αυτής της σελίδας είναι κρίση που κανένα εργαλείο δεν μπορεί να αναλάβει. Αυτό που μπορεί να κάνει ένα εργαλείο είναι να εγγυηθεί ότι μια μετάφραση δεν μπορεί να αλλάξει τη δομή της πρότασης που μεταφράζει — δεν μπορεί να παραλείψει μια τιμή, να επινοήσει μία, να αναμορφοποιήσει μία ή να απλώσει το χέρι μέσα στα αντικείμενά σας — και να το πει με μια πρόταση πάνω στην οποία μπορεί να δράσει ο άνθρωπος που πρέπει να το διορθώσει. Αυτό είναι όλο κι όλο ό,τι υπόσχεται αυτή η βιβλιοθήκη, και τα υπόλοιπα αυτού του ιστότοπου είναι το πώς την κρατά.