Online Casino
�

Passare da NibTool a IBTool

Matteo - 27 Novembre 2007

Aggiornamento 22/02/08: sono stato avvertito di un bug e di un problema con la licenza del codice sottostante. Il codice da questo momento � da considerarsi sotto licenza BSD e i tre script (corretti) possono essere scaricati cliccando qui.

�

Abbiamo avuto pi� volte modo di parlare di nibtool, quello che fino a ieri era lo strumento principale fornito da Apple (tra quelli a basso livello) per eseguire la localizzazione delle proprie applicazioni su OS X.

Un paio di settimane fa installo Leopard e XCode 3.0. Uno spettacolo e tutto, ma dov'� nibtool??? Non c'�, sostituito da ibtool.

Un veloce man ibtool mostra una discreta compatibilit� di comandi tra i due, cambiano un po' i nomi dei parametri ma, almeno a leggere l�, ci si possono fare le stesse cose e, naturalmente, qualcosina di pi�.

Faccio qualche prova e scopro che, ahim�, non solo � cambiato il file di stringhe, ma � anche decuplicato in dimensione: mi sono subito immaginato la contentezza dei nostri gentilissimi traduttori volontari nel ricevere, invece del solito file da 300 righe compresi spazi bianchi e cose gi� tradotte, 3000 righe in un formato assolutamente poco adatto alla fruizione umana.

Confrontiamo una tipica stringa "vecchio stile":

/* NSMenuItem : <title:To clipboard> (oid:494) */
"To clipboard" = "Sugli appunti";

con una "nuovo stile":

/* Class = "NSMenuItem"; title = "To clipboard"; ObjectID = "494"; */
"494.title" = "Sugli appunti";

Fin qui non ci sarebbe molta differenza (anche se gi� mi sembra molto meno chiaro), ma il problema pi� grosso � che vengono aggiunte tutte le stringhe, anche quelle non definite. Ad esempio, per un campo di testo a cui nel file nib non avevo associato alcuna stringa, il file generato da ibtool contiene tutte queste righe:

/* Class = "NSTextField"; designAccessibilityDescription = ""; ObjectID = "398"; */
"398.designAccessibilityDescription" = "";

/* Class = "NSTextField"; designAccessibilityHelp = ""; ObjectID = "398"; */
"398.designAccessibilityHelp" = "";

/* Class = "NSTextField"; gToolTip = ""; ObjectID = "398"; */
"398.gToolTip" = "";

Un traduttore dovrebbe veramente affrontare 3000 righe cos�?

Inoltre eventuali doppioni vengono messi tutte le volte: se la stessa stringa appare in due controlli diversi, va tradotta due volte. Ok questo potrebbe essere utile per differenziare la traduzione in base al contesto, ma personalmente non mi � mai servito: la differenza pu� essere resa anche in Inglese.

Una piccola nota / bug / avvertenza: eventuali testi nei controlli NSTextView non vengono inseriti nei file di stringhe da ibtool, come invece faceva nibtool. In realt� la traduzione di quei testi con nibtool non ha mai funzionato, perch� in realt� sono testi con attributi RTF e venivano tradotti lasciando inalterata la posizione dei cambi di stile… insomma un macello :) per� da tenere a mente nel caso si usassero, magari senza stili nei testi. La cosa migliore � sempre creare dei file RTF nelle risorse e caricare quello giusto per la lingua corrente a runtime, � molto semplice.�

L'alternativa rimane quella di far modificare ai traduttori direttamente i file nib, la cui gestione diretta mi sembra molto migliorata in ibtool. Questa soluzione � per� tutt'altro che ottimale: non solo tutti i traduttori devono aver installato XCode per poter utilizzare InterfaceBuilder (e non parliamo per ora dei plugin, altra nota molto dolente), ma nella traduzione diretta alcune stringhe pi� nascoste (ad esempio i tooltip o i sottomenu) potrebbero essere dimenticate: questo significa che, nel ricevere ogni traduzione, dovrei controllare personalmente tutto quanto… Come si capisce non � cosa…

Insomma alla fine ho deciso di mantenere un'interfaccia con i traduttori identica a quella precedente: stessi file su cui lavorare, stesso formato. Il resto � impiccio mio.

E l'impiccio � una doppia trasformazione: la prima che trasforma i file di stringhe generati da ibtool in quelli "vecchio stile", simili a quelli generati da nibtool; la seconda che genera file di stringhe tradotti che ibtool sia in grado di leggere, a partire dai file vecchio stile tradotti.

Schematicamente i passaggi sono:

  1. generazione con ibtool delle stringhe, a partire dai file nib;
  2. conversione (automatica) in stringhe "vecchio stile";
  3. traduzione delle stringhe "vecchio stile";
  4. traduzione (automatica) delle stringhe generate da ibtool sulla base di quelle "vecchio stile" tradotte;
  5. generazione con ibtool dei file nib tradotti.

Il passo 1 � semplice, utilizzando ibtool al posto di nibtool, con una linea di comando tipo:

ibtool --generate-stringsfile English.lproj/MainMenu_ib.strings English.lproj/MainMenu.nib

Il passo 2 lo eseguo con uno script Python, chiamato gen_nib_strings.py, che prende in ingresso un file generato da ibtool e ne crea uno "vecchio stile":

#!/usr/bin/python
## generate a strings file compatible with nibtool from a strings file generated
## with ibtool --generate-stringsfile

<ved. file allegato>

Dopo la conversione utilizzo lo script discusso nel precedente articolo per fare l'integrazione dei file di stringhe.�

Il passo 3 � meglio lasciarlo alle manine dei madrelingua :)

Per il passo 4 impiego un altro script Python, translate_ib_strings.py, che prende il file di prima generato con ibtool, quello tradotto nel passo 3 e crea un nuovo file nel formato riconosciuto da ibtool ma con le stringhe tradotte:

#!/usr/bin/python
## translate a file generated with ibtool --generate-stringsfile :
## ��� ��� /* Class = "NSMenu"; title = "Menu"; ObjectID = "305"; */
## ��� ��� "305.title" = "Menu";
## with a strings file in the style of nibtool:
## ��� ��� /* NSMenu : <title:Menu> (oid:305) */
## ��� ��� "Menu" = "Menu";

<ved. file allegato>

Il passo 5 richiede l'uso di ibtool, con una riga di comando del tipo:

ibtool --strings-file Italian.lproj/MainMenu_ib.strings English.lproj/MainMenu.nib --write Italian.lproj/MainMenu.nib

Il gioco � fatto.�

Weblog Koan Progetti Foto Contatti
�