'From etoys2.2 of 27 September 2007 [latest update: #1680] on 2 October 2007 at 9:46:03 pm'! "Change Set: sortedPOFile-tak Date: 2 October 2007 Author: Takashi Yamamiya #3596 Sorting in pot files A small fix for GetTextNormCR-KR, and unit test for GTExpByDomain-KR is included. "! !GetTextExporter2 commentStamp: '' prior: 0! Export translations to gettext format divided into categories. "Export gettext template files" GetTextExporter2 new exportTemplate. "Export translation files for current locale" GetTextExporter2 new exportTranslator: (NaturalLanguageTranslator availableForLocaleID: LocaleID current). "Export all gettext template and po files." GetTextExporter2 exportAll. "To register a class category as a new domain" TextDomainManager registerClassCategory: 'Morphic-Books' domain: 'Book'. "Remove a class category" TextDomainManager unregisterClassCategory: 'Morphic-Books'.! TestCase subclass: #GettextTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Multilingual-Editor'! !GettextTest commentStamp: 'tak 10/2/2007 15:42' prior: 0! Tests for translation related issue. LanguageEditorTest will be merged to this class after GetTextExporter and GetTextExporter2 are merged. self buildSuite run! TestCase subclass: #LanguageEditorTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Multilingual-Editor'! !GetTextExporter2 methodsFor: 'private' stamp: 'tak 10/2/2007 21:42'! exportBody: literals translator: translator "Export a gettext file body. literals is a dictionary of keyword -> #(MethodReference...) in the textDomain." | sorted literal sortInCategory methodReferences | sortInCategory := literals associations collect: [:assoc | assoc key -> assoc value asArray sort]. sorted := sortInCategory sort: [:a :b | a value first printString < b value first printString or: [ a value first printString = b value first printString and: [a key < b key]]]. sorted do: [:assoc | literal := assoc key. methodReferences := assoc value. self exportRecordHeader: (methodReferences inject: '' into: [:result :occur | result , occur classSymbol asString , '>>' , occur methodSymbol asString , ' ']). self exportPhrase: literal translation: (translator ifNil: [''] ifNotNil: [translator translations at: literal ifAbsent: ''])]! ! !GetTextExporter2 methodsFor: 'private' stamp: 'tak 10/2/2007 21:25'! exportPhrase: phraseString translation: translationString | normalizedTrans tmp transStartsWithCR transEndsWithCR| phraseString isEmpty ifTrue: [^ self]. self exportTag: 'msgid' msg: phraseString. translationString size = 0 ifTrue: [ normalizedTrans _ '' ] ifFalse: [ transEndsWithCR _ translationString last = (Character cr). phraseString last = (Character cr) ifTrue: [ transEndsWithCR ifTrue: [ normalizedTrans _ translationString ] ifFalse: [ normalizedTrans _ translationString , String cr ] ] ifFalse: [ transEndsWithCR ifTrue: [ normalizedTrans _ translationString allButLast ] ifFalse: [ normalizedTrans _ translationString ] ]. transStartsWithCR _ normalizedTrans first = (Character cr). phraseString first = (Character cr) ifTrue: [ transStartsWithCR ifFalse: [ tmp _ (Character cr asString) , normalizedTrans. normalizedTrans _ tmp. ] ] ifFalse: [ transStartsWithCR ifTrue: [ normalizedTrans _ normalizedTrans allButFirst ] ] ]. self exportTag: 'msgstr' msg: normalizedTrans. stream cr! ! !GetTextExporter2 methodsFor: 'private' stamp: 'tak 10/2/2007 16:57'! export: literals translator: translator domain: domainName | fileName | "Export a gettext file in a category. literals is a dictionary of keyword -> #(MethodReference...) in the textDomain." fileName := self dirNameDomain: domainName translator: translator. [stream := FileStream forceNewFileNamed: fileName. stream wantsLineEndConversion: true. stream lineEndConvention: #lf. stream converter: UTF8TextConverter new. self exportHeader: domainName. self exportBody: literals translator: translator] ensure: [stream close]! ! !GetTextExporter2 methodsFor: 'accessing' stamp: 'tak 10/2/2007 15:53'! stream ^ stream! ! !GetTextExporter2 methodsFor: 'accessing' stamp: 'tak 10/2/2007 15:53'! stream: aStream stream := aStream! ! !GettextTest methodsFor: 'testing' stamp: 'tak 10/2/2007 17:51'! testExportBody "self debug: #testExportBody" | literals exporter | literals := Dictionary new. literals at: 'key1' put: {MethodReference new setStandardClass: Object methodSymbol: #method1. MethodReference new setStandardClass: Morph methodSymbol: #method2}. exporter := GetTextExporter2 new. exporter stream: '' writeStream. exporter exportBody: literals translator: nil. self assert: exporter stream contents = '#: Morph>>method2 Object>>method1 msgid "key1" msgstr "" '. literals at: 'key3' put: {MethodReference new setStandardClass: Morph methodSymbol: #another}. literals at: 'key2' put: {MethodReference new setStandardClass: Morph methodSymbol: #another}. exporter stream: '' writeStream. exporter exportBody: literals translator: nil. self assert: exporter stream contents = '#: Morph>>another msgid "key2" msgstr "" #: Morph>>another msgid "key3" msgstr "" #: Morph>>method2 Object>>method1 msgid "key1" msgstr "" '. ! ! !GettextTest methodsFor: 'testing' stamp: 'tak 10/2/2007 15:54'! testGettextExportFormat "self debug: #testGettextExportFormat" | exporter | exporter := GetTextExporter2 new. exporter stream: '' writeStream. exporter exportPhrase: 'source' translation: 'translated'. self assert: exporter stream contents = 'msgid "source" msgstr "translated" '. exporter stream: '' writeStream. exporter exportPhrase: '"quoted" phrase' translation: '"QUOTED" PHRASE'. self assert: exporter stream contents = 'msgid "\"quoted\" phrase" msgstr "\"QUOTED\" PHRASE" '! ! !GettextTest methodsFor: 'testing' stamp: 'tak 10/2/2007 15:54'! testGettextExportFormatMultiLine "self debug: #testGettextExportFormatMultiLine" | exporter | exporter := GetTextExporter2 new. exporter stream: '' writeStream. exporter exportPhrase: 'Multiline Identifier' translation: 'Multiline Phrase'. self assert: exporter stream contents = 'msgid "" "Multiline\n" "Identifier" msgstr "" "Multiline\n" "Phrase" '. ! ! !GettextTest methodsFor: 'testing' stamp: 'tak 10/2/2007 15:51'! testReplacement "self debug: #testReplacement" self assert: (GetTextExporter2 new formatString: 'test') = ('test'). self assert: (GetTextExporter2 new formatString: 't"es"t') = ('t\"es\"t'). self assert: (GetTextExporter2 new formatString: 't\est') = ('t\\est'). self assert: (GetTextExporter2 new formatString: 'te', String cr, 'st') = ('te\nst'). "" self assert: (GetTextImporter new formatString: 'test') = 'test'. self assert: (GetTextImporter new formatString: 'te\nst') = ('te', String cr, 'st'). self assert: (GetTextImporter new formatString: 'te\\nst') = ('te\nst'). ! ! !GettextTest methodsFor: 'testing' stamp: 'tak 10/2/2007 15:48'! testTextDomain "self debug: #testTextDomain" self assert: TextDomainManager defaultDomain = 'etoys'. TextDomainManager registerClassCategory: 'Multilingual-Editor' domain: 'translation'. self assert: (TextDomainManager domainForClassCategory: 'Multilingual-Editor') = 'translation'. self assert: (TextDomainManager domainForClassCategory: 'Kernel-Objects') = 'etoys'. self assert: (TextDomainManager domainForClassCategory: 'anonymous') = 'etoys'. TextDomainManager unregisterClassCategory: 'Multilingual-Editor'. self assert: (TextDomainManager domainForClassCategory: 'Multilingual-Editor') = 'etoys'! ! LanguageEditorTest removeSelector: #testGettextExportFormat! LanguageEditorTest removeSelector: #testGettextExportFormatMultiLine! LanguageEditorTest removeSelector: #testReplacement! !GettextTest reorganize! ('testing' testExportBody testGettextExportFormat testGettextExportFormatMultiLine testReplacement testTextDomain) ! GetTextExporter2 removeSelector: #export:! GetTextExporter2 removeSelector: #export:translator:fileNamed:! !GetTextExporter2 reorganize! ('exporting' appendTranslations: dirNameCategory:translator: dirNameDomain:translator: exportTemplate exportTranslator:) ('private' appendStringReceivers: appendStringReceivers:into: appendVocabularies: appendVocabulary:domains: createHeaders currentDateAndTime exportBody:translator: exportHeaderLineKey:value: exportHeader: exportPhrase:translation: exportRecordHeader: exportTag:msg: exportTag:singleLine: export:translator:domain: formatReplacements formatString: getTextDomainForClassCategory:) ('accessing' stream stream:) !