[squeak-dev] The Inbox: GetText-fbs.30.mcz

H. Hirzel hannes.hirzel at gmail.com
Mon May 13 05:01:56 UTC 2013


This and  the previous mail is about what we have discussed earlier
(February 2013).
I do not have Squeak ready at the moment. Could somebody else please
have a look at it if the changes are fine?

--Hannes

On Sun, 12 May 2013 15:17:31.42 0000, commits at source.squeak.org
<commits at source.squeak.org> wrote:
> Frank Shearar uploaded a new version of GetText to project The Inbox:
> http://source.squeak.org/inbox/GetText-fbs.30.mcz
>
> ==================== Summary ====================
>
> Name: GetText-fbs.30
> Author: fbs
> Time: 12 May 2013, 4:17:30.395 pm
> UUID: 492bd879-7a58-4af2-b0f4-31d90a5b00c3
> Ancestors: GetText-fbs.29
>
> Move localization classes/methods to System-Localization. Remove the now
> empty GetText-Localization system category.
>
> =============== Diff against GetText-fbs.29 ===============
>
> Item was added:
> + SystemOrganization addCategory: #'GetText-Editor'!
>
> Item was removed:
> - SystemOrganization addCategory: #'GetText-Editor'!
> - SystemOrganization addCategory: #'GetText-Localization'!
>
> Item was removed:
> - NaturalLanguageTranslator subclass: #GetTextTranslator
> - 	instanceVariableNames: 'moFiles'
> - 	classVariableNames: 'LocaleDirsForDomain SystemDefaultLocaleDirs
> UserDefaultLocaleDirs'
> - 	poolDictionaries: ''
> - 	category: 'GetText-Localization'!
> -
> - !GetTextTranslator commentStamp: '<historical>' prior: 0!
> - emulation of gettext runtime
> - Known limitation:
> -      currently doesn't support plural forms.
> - !
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>addSystemDefaultLocaleDir: (in
> category 'translation data layout') -----
> - addSystemDefaultLocaleDir: dir
> - 	"new dir will be put as first"
> -  	self systemDefaultLocaleDirs addFirst: dir!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>availableLanguageLocaleIDs (in
> category 'accessing') -----
> - availableLanguageLocaleIDs
> - 	"GetTextTranslator availableLanguageLocaleIDs"
> - 	| ids dirs localeDirForLang directoryNames |
> - 	ids := Set new.
> - 	dirs := Set new.
> - 	dirs addAll: LocaleDirsForDomain values.
> - 	dirs addAll: self defaultLocaleDirs.
> - 	dirs do: [:dir |
> - 		| localesDir |
> - 		localesDir := FileDirectory on: dir.
> - 		directoryNames := [localesDir directoryNames] on: InvalidDirectoryError
> do: [:e | #()].
> - 		directoryNames
> - 				do: [:langDirName |
> - 					| localeID  |
> - 					localeID := LocaleID posixName: langDirName.
> - 					localeDirForLang := localesDir directoryNamed: (self
> langDirNameForLocaleID: localeID).
> - 					localeDirForLang ifNotNil: [
> - 						(localeDirForLang fileNamesMatching: '*.mo') ifNotEmpty: [ids add:
> localeID]
> - 					]
> - 				].
> - 	].
> - 	^ids!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>defaultLocaleDirs (in category
> 'translation data layout') -----
> - defaultLocaleDirs
> - 	| dirs |
> - 	dirs := OrderedCollection new.
> - 	UserDefaultLocaleDirs ifNotNil: [dirs addAll: UserDefaultLocaleDirs].
> - 	dirs addAll: self systemDefaultLocaleDirs.
> - 	^dirs
> - !
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>findMOForLocaleID:domain: (in
> category 'private') -----
> - findMOForLocaleID: id domain: aDomainName
> - 	| sepa langSubDir path |
> - 	sepa := FileDirectory slash.
> - 	langSubDir := self langDirNameForLocaleID: id.
> - 	(self localeDirsForDomain: aDomainName)
> - 		do: [:each |
> - 			path := each , sepa , langSubDir, sepa , (self moNameForDomain:
> aDomainName).
> - 			[(FileDirectory default fileExists: path)
> - 				 ifTrue: [^path]] on: InvalidDirectoryError do: [:e | ^nil]].
> - 	^nil.!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>initialize (in category 'class
> initialization') -----
> - initialize
> - 	SystemDefaultLocaleDirs := OrderedCollection new.
> - 	UserDefaultLocaleDirs := OrderedCollection new.
> - 	LocaleDirsForDomain := Dictionary new.!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>langDirNameForLocaleID: (in
> category 'private') -----
> - langDirNameForLocaleID: id
> - 	"returns relative path from locale directory to actual directory
> containing MOs"
> - 	^(id posixName) , (FileDirectory slash)  , 'LC_MESSAGES'!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>localeDirForDomain: (in category
> 'translation data layout') -----
> - localeDirForDomain: aDomainName
> - 	"returns registered localeDirectory for the textdomain. returns nil if
> not registered"
> - 	^LocaleDirsForDomain at: aDomainName ifAbsent: [nil]!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>localeDirsForDomain (in category
> 'private') -----
> - localeDirsForDomain
> - 	^LocaleDirsForDomain ifNil: [LocaleDirsForDomain := Dictionary new]!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>localeDirsForDomain: (in category
> 'translation data layout') -----
> - localeDirsForDomain: aDomainName
> - 	"returns collection of locale directories for text domain.
> - 	This includes user defined one for the domain, user defaults and system
> defaults"
> - 	| dirs dir |
> - 	dirs := OrderedCollection new.
> - 	dir := self localeDirForDomain: aDomainName.
> - 	dir ifNotNil: [dirs add: dir].
> - 	dirs addAll:  self defaultLocaleDirs.
> - 	^dirs!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>moNameForDomain: (in category
> 'private') -----
> - moNameForDomain: domainName
> - 	^domainName , '.mo'!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>newForLocaleID: (in category
> 'instance creation') -----
> - newForLocaleID: id
> - 	^self new localeID: id!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>privateStartUp (in category 'class
> initialization') -----
> - privateStartUp
> - 	self setupLocaleDirs.
> - 	self availableLanguageLocaleIDs do: [ :localeID |
> - 		NaturalLanguageTranslator translators
> - 				at: localeID
> - 				put: (self newForLocaleID: localeID).
> - 	]!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>setLocaleDir:forDoamin: (in
> category 'translation data layout') -----
> - setLocaleDir: path forDoamin: aDomainName
> - 	self LocaleDirsForDomain
> - 		at: aDomainName
> - 		put: path.!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>setupLocaleDirs (in category
> 'translation data layout') -----
> - setupLocaleDirs
> - 	| dirs sepa localesDirName |
> - 	sepa := FileDirectory slash.
> - 	SystemDefaultLocaleDirs := nil.
> - 	dirs := self systemDefaultLocaleDirs.
> - 	localesDirName := 'locale'.
> - 	dirs add:  (SmalltalkImage current imagePath) , sepa , localesDirName.
> - 	dirs add:  (SmalltalkImage current vmPath) , sepa , localesDirName.
> - 	^dirs!
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>systemDefaultLocaleDirs (in
> category 'translation data layout') -----
> - systemDefaultLocaleDirs
> - 	^SystemDefaultLocaleDirs ifNil: [SystemDefaultLocaleDirs :=
> OrderedCollection new]
> - !
>
> Item was removed:
> - ----- Method: GetTextTranslator class>>userDefaultLocaleDirs (in category
> 'translation data layout') -----
> - userDefaultLocaleDirs
> - 	^UserDefaultLocaleDirs ifNil: [UserDefaultLocaleDirs := OrderedCollection
> new]
> - !
>
> Item was removed:
> - ----- Method: GetTextTranslator>>atRandom (in category 'accessing') -----
> - atRandom
> -
> - 	| v |
> - 	moFiles ifEmpty: [^ ''].
> - 	(v := moFiles atRandom value) ifNil: [^ ''].
> - 	^ v atRandom.
> - !
>
> Item was removed:
> - ----- Method: GetTextTranslator>>domainRegistered: (in category
> 'accessing') -----
> - domainRegistered: aDomainName
> - 	"only current translator actually load the MO, to minimize loading time.
> - 	 other translator will load anyway when it goes current"
> - 	(self class current == self)
> - 		ifTrue: [self moFileForDomain: aDomainName].
> - 	!
>
> Item was removed:
> - ----- Method: GetTextTranslator>>domainUnregistered: (in category
> 'accessing') -----
> - domainUnregistered: aDomainName
> - 	moFiles removeKey: aDomainName ifAbsent: [^self]
> - 	!
>
> Item was removed:
> - ----- Method: GetTextTranslator>>initialize (in category
> 'initialize-release') -----
> - initialize
> - 	moFiles := Dictionary new.!
>
> Item was removed:
> - ----- Method: GetTextTranslator>>isDomainLoaded: (in category 'accessing')
> -----
> - isDomainLoaded: aDomainName
> - 	| mo |
> - 	mo := moFiles at: aDomainName ifAbsent: [nil].
> - 	^mo isNil not.
> - !
>
> Item was removed:
> - ----- Method: GetTextTranslator>>loadMOFileForDomain: (in category
> 'private') -----
> - loadMOFileForDomain: aDomainName
> - 	| moName |
> - 	moName := self class findMOForLocaleID: self localeID
> - 								domain: aDomainName.
> - 	moName notNil
> - 			 ifTrue: [^MOFile new load: moName
> - 								localeID: self localeID]
> - 			ifFalse: [^nil]
> - !
>
> Item was removed:
> - ----- Method: GetTextTranslator>>loadMOFiles (in category 'accessing')
> -----
> - loadMOFiles
> - 	TextDomainManager allKnownDomains
> - 		do: [:domainName |
> - 			self moFileForDomain: domainName
> - 		].!
>
> Item was removed:
> - ----- Method: GetTextTranslator>>moFileForDomain: (in category 'private')
> -----
> - moFileForDomain: domainName
> - 	^moFiles at: domainName ifAbsentPut: [self loadMOFileForDomain:
> domainName]!
>
> Item was removed:
> - ----- Method: GetTextTranslator>>reloadMOFiles (in category 'accessing')
> -----
> - reloadMOFiles
> - 	moFiles := Dictionary new.
> - 	self loadMOFiles.!
>
> Item was removed:
> - ----- Method: GetTextTranslator>>setCurrent (in category 'language
> switching') -----
> - setCurrent
> - 	"ensure actual contents of MOs is loaded on switching language"
> - 	self loadMOFiles!
>
> Item was removed:
> - ----- Method: GetTextTranslator>>translate:inDomain: (in category
> 'translation') -----
> - translate: aString inDomain: aDomainName
> - 	| mo |
> - 	mo := self moFileForDomain: aDomainName.
> - 	^mo isNil
> - 		ifTrue: [aString]
> - 		ifFalse: [mo translationFor: aString]
> - !
>
> Item was removed:
> - Object subclass: #MOFile
> - 	instanceVariableNames: 'localeID fileName isLittleEndian magic revision
> nStrings originalTableOffset translatedTableOffset hashTableSize
> hashTableOffset hashTable originalStrings translatedStrings translations'
> - 	classVariableNames: 'Cr Lf'
> - 	poolDictionaries: ''
> - 	category: 'GetText-Localization'!
> -
> - !MOFile commentStamp: '<historical>' prior: 0!
> - Wrapper for MO file of gettext.
> - Known limitation:
> - 	currently don't support prural form.
> - 	translation strings have to be encoded in utf-8.
> -
> - Implementation notes:
> - 	Testing on XO showed emulation of hash search without plugin + on demand
> loading is slow.
> - 	The test also showed conversion of utf8 string to Squeak's String is
> really slow (especially for non-latin language).
> - 	so in this version, all of original/translated strings are loaded on
> initiaization,
> - 	but "translated strings" is left as ByteString on loading time, to reduce
> loading time.
> - 	After that the translated string is converted on demand.
> - !
>
> Item was removed:
> - ----- Method: MOFile class>>fileName:localeID: (in category 'instance
> creation') -----
> - fileName: path localeID: id
> - 	^self new
> - 			load:path localeID: id!
>
> Item was removed:
> - ----- Method: MOFile class>>initialize (in category 'class
> initialization') -----
> - initialize
> - 	Cr := Character cr.
> - 	Lf := Character lf.
> - !
>
> Item was removed:
> - ----- Method: MOFile>>atRandom (in category 'public') -----
> - atRandom
> -
> - 	^ self translatedString:nStrings atRandom.
> - !
>
> Item was removed:
> - ----- Method: MOFile>>fileName (in category 'public') -----
> - fileName
> - 	^fileName!
>
> Item was removed:
> - ----- Method: MOFile>>fileName: (in category 'public') -----
> - fileName: path
> - 	fileName := path!
>
> Item was removed:
> - ----- Method: MOFile>>hashPjw: (in category 'experimental') -----
> - hashPjw: aString
> - 	"So called `hashpjw' function by P.J. Weinberger
> -    	[see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
> -    	1986, 1987 Bell Telephone Laboratories, Inc.] "
> - 	| stringSize hash g |
> - 	stringSize := aString size.
> - 	hash := 0.
> - 	1 to: stringSize do: [:pos |
> - 		hash := hash bitShift: 4.
> - 		hash := hash + ((aString at: pos) asInteger).
> - 		g := hash bitAnd: 16rF0000000.
> - 		g = 0 ifFalse: [
> - 			hash := hash  bitXor: (g bitShift: -24).
> - 			hash := hash bitXor: g.
> - 		]
> - 	].
> - 	^hash.
> - !
>
> Item was removed:
> - ----- Method: MOFile>>load1:localeID: (in category 'experimental') -----
> - load1: aFileName localeID: id
> - 	"CASE1:
> - 		all of strings are loaded.
> - 		translation strings are converted to Squeak format on load time.
> - 		original-string/index pairs are registerd to Dictionary on load time.
> - 		hash search can't be used"
> - 	| strm originalTable translatedTable |
> - 	localeID := id.
> - 	strm := FileStream readOnlyFileNamed: aFileName.
> - 	fileName := aFileName.
> - 	[
> - 		self loadHeader: strm.
> - 		originalTable := self loadStringPointers: strm
> - 								offset: originalTableOffset.
> -
> - 		originalStrings := self loadStrings: strm
> - 								pointers: originalTable.
> -
> - 		translatedTable := self loadStringPointers: strm
> - 								offset: translatedTableOffset.
> -
> - 		translatedStrings := self loadStrings: strm
> - 								pointers: translatedTable
> - 								encoding: 'utf8'
> - 								languageEnvironment: (Locale localeID: localeID)
> languageEnvironment .
> -
> - 		translations := Dictionary new.
> - 		1 to: nStrings do: [:index |
> - 			| key |
> - 			key := originalStrings at: index.
> - 			translations at: key put: index.
> - 		].
> - 		originalTable := nil.
> - 	] ensure: [strm close].!
>
> Item was removed:
> - ----- Method: MOFile>>load4:localeID: (in category 'experimental') -----
> - load4: aFileName localeID: id
> - 	"CASE4:
> - 		all of strings are loaded.
> - 		loading and conversion of translation strings to Squeak format is
> executed on initialization time.
> - 		only hash search can be used"
> - 	| strm originalTable translatedTable |
> - 	localeID := id.
> - 	strm := FileStream readOnlyFileNamed: aFileName.
> - 	fileName := aFileName.
> - 	[
> - 		self loadHeader: strm.
> - 		self loadHashTable: strm.
> - 		originalTable := self loadStringPointers: strm
> - 								offset: originalTableOffset.
> -
> - 		originalStrings := self loadStrings: strm
> - 								pointers: originalTable.
> -
> - 		translatedTable := self loadStringPointers: strm
> - 								offset: translatedTableOffset.
> -
> - 		translatedStrings := self loadStrings: strm
> - 								pointers: translatedTable
> - 								encoding: 'utf-8'
> - 								languageEnvironment: (Locale localeID: localeID)
> languageEnvironment .
> - 	] ensure: [strm close].!
>
> Item was removed:
> - ----- Method: MOFile>>load:localeID: (in category 'public') -----
> - load: aFileName localeID: id
> - 	"all of original/translated strings are loaded.
> - 		but conversion of translation string (in utf-8 bytestring) to Squeak
> format will be defered.
> - 		original-string/index pairs are registerd to Dictionary on load time.
> - 		hash search can't be used"
> - 	| strm originalTable translatedTable |
> - 	localeID := id.
> - 	strm := FileStream readOnlyFileNamed: aFileName.
> - 	fileName := aFileName.
> - 	[
> - 		self loadHeader: strm.
> - 		originalTable := self loadStringPointers: strm
> - 								offset: originalTableOffset.
> -
> - 		originalStrings := self loadStrings: strm
> - 								pointers: originalTable.
> -
> - 		translatedTable := self loadStringPointers: strm
> - 								offset: translatedTableOffset.
> -
> - 		translatedStrings := self loadStrings: strm
> - 								pointers: translatedTable.
> -
> - 		translations := Dictionary new: nStrings * 2.  "make too enough room to
> avoid #grow"
> - 		1 to: nStrings do: [:index |
> - 			| key |
> - 			key := originalStrings at: index.
> - 			translations at: key put: index.
> - 		].
> - 		originalStrings := nil.
> - 	] ensure: [strm close].!
>
> Item was removed:
> - ----- Method: MOFile>>loadHashTable: (in category 'experimental') -----
> - loadHashTable: strm
> - 	| entry |
> - 	hashTable := IntegerArray  ofSize: hashTableSize.
> - 	strm binary.
> - 	strm position: hashTableOffset.
> - 	1 to: hashTableSize do: [:index |
> - 		entry := self nextInt32From: strm.
> - 		hashTable at:  index put: entry.
> - 	]!
>
> Item was removed:
> - ----- Method: MOFile>>loadHeader: (in category 'private') -----
> - loadHeader: strm
> - 	strm binary.
> - 	magic :=  strm uint32.
> - 	magic = 16rDE120495
> - 		ifTrue: [isLittleEndian := true]
> - 		ifFalse: [
> - 			magic = 16r950412DE
> - 				ifTrue: [isLittleEndian := false]
> - 				ifFalse: [ self error: 'invalid MO']
> - 		].
> - 	revision := self nextInt32From: strm.
> - 	nStrings := self nextInt32From: strm.
> - 	originalTableOffset := self nextInt32From: strm.
> - 	translatedTableOffset := self nextInt32From: strm.
> - 	hashTableSize := self nextInt32From: strm.
> - 	hashTableOffset := self nextInt32From: strm.
> - !
>
> Item was removed:
> - ----- Method: MOFile>>loadString:pointer:length: (in category 'private')
> -----
> - loadString: strm pointer: top  length: len
> - 	| str |
> - 	str := ByteString new: len.
> - 	strm position:  top.
> - 	strm nextInto: str.
> - 	^str replaceAll: Lf with: Cr.
> - !
>
> Item was removed:
> - ----- Method: MOFile>>loadStringPointers:offset: (in category 'private')
> -----
> - loadStringPointers: strm offset: tableOffset
> - 	"returns tupple {arrayOfOffsetToString  arrayOfLengthOfString}"
> - 	| offsetTable lenTable len offset tupple |
> - 	offsetTable := IntegerArray new: nStrings.
> - 	lenTable := IntegerArray new: nStrings.
> - 	strm binary.
> - 	strm position: tableOffset.
> - 	1 to: nStrings do: [:index |
> - 		len := self nextInt32From: strm.
> - 		offset := self nextInt32From: strm.
> - 		offsetTable at: index put: offset.
> - 		lenTable at: index put: len.
> - 	].
> - 	tupple := Array new: 2.
> - 	tupple at: 1 put: offsetTable.
> - 	tupple at: 2 put:  lenTable.
> - 	^tupple
> - !
>
> Item was removed:
> - ----- Method: MOFile>>loadStrings:pointers: (in category 'private') -----
> - loadStrings: strm pointers: table
> - 	^self loadStrings: strm pointers: table encoding: nil
> languageEnvironment: nil
> - !
>
> Item was removed:
> - ----- Method: MOFile>>loadStrings:pointers:encoding:languageEnvironment:
> (in category 'private') -----
> - loadStrings: strm pointers: tupple encoding: encodingName
> languageEnvironment: env
> - 	| strings rawStr str offsetTable lenTable |
> - 	offsetTable :=  tupple first.
> - 	lenTable := tupple second.
> - 	strings := Array new: nStrings.
> - 	1 to: nStrings do: [:index |
> - 		rawStr := self loadString: strm
> - 					pointer:  (offsetTable at: index)
> - 					length: (lenTable at: index).
> - 		str := encodingName isNil ifTrue: [rawStr]
> - 						ifFalse: [ encodingName = 'utf8'
> - 									ifTrue: [rawStr utf8ToSqueak applyLanguageInfomation: env]
> - 									ifFalse: [self error: 'this encoding isn''t supported']
> - 						].
> - 		strings at: index put: str.
> - 	].
> - 	^strings.!
>
> Item was removed:
> - ----- Method: MOFile>>nextInt32From: (in category 'private') -----
> - nextInt32From: strm
> - 	^isLittleEndian
> - 			ifTrue: [^strm nextLittleEndianNumber: 4]
> - 			ifFalse: [^strm nextInt32]!
>
> Item was removed:
> - ----- Method: MOFile>>originalString: (in category 'private') -----
> - originalString: index
> - 	^originalStrings at: index.
> - !
>
> Item was removed:
> - ----- Method: MOFile>>searchByDictionary: (in category 'public') -----
> - searchByDictionary: aString
> - 	| index |
> - 	index := translations at: aString ifAbsent: [^nil].
> - 	^self translatedString: index
> - 	
> - !
>
> Item was removed:
> - ----- Method: MOFile>>searchByHash: (in category 'experimental') -----
> - searchByHash: aString
> - 	| hashValue nstr index incr key |
> - 	hashValue :=  self hashPjw: aString.
> - 	incr := 1 + (hashValue \\ (hashTableSize -2)).
> - 	index := (hashValue \\ hashTableSize) .
> - 	[ 	nstr := (hashTable at: index +1 ).
> - 		nstr = 0 ifTrue: [^nil].
> - 		key := self originalString: nstr.
> - 		key = aString ifTrue: [^self translatedString: nstr].
> - 		index >= (hashTableSize - incr)
> - 				ifTrue: [index := index - (hashTableSize - incr)  ]
> - 				ifFalse:[index := index + incr].	
> - 	] doWhileTrue: true.!
>
> Item was removed:
> - ----- Method: MOFile>>testSearchByDictionary (in category 'experimental')
> -----
> - testSearchByDictionary
> - 	InternalTranslator allKnownPhrases
> - 		do: [:each |
> - 			self searchByDictionary: each
> - 		].
> - 	!
>
> Item was removed:
> - ----- Method: MOFile>>testSearchByHash (in category 'experimental') -----
> - testSearchByHash
> - 	InternalTranslator allKnownPhrases
> - 		do: [:each |
> - 			self searchByHash: each
> - 		].
> - 	!
>
> Item was removed:
> - ----- Method: MOFile>>translateByHash: (in category 'experimental') -----
> - translateByHash: aString
> - 	| trans |
> - 	trans := self searchByHash: aString.
> - 	trans isNil ifTrue: [^aString]
> - 			ifFalse: [^trans].
> - !
>
> Item was removed:
> - ----- Method: MOFile>>translatedString: (in category 'private') -----
> - translatedString: index
> - 	"KNOWN PROBLEM: conversion is executed everytimes this method called"
> - 	| str |
> - 	str := translatedStrings at: index.
> -
> - 	^str utf8ToSqueak applyLanguageInfomation: (Locale localeID: localeID)
> languageEnvironment.
> - !
>
> Item was removed:
> - ----- Method: MOFile>>translationFor: (in category 'public') -----
> - translationFor: aString
> - 	| |
> - 	aString size = 0 ifTrue: [^ '']. "Gettext header"
> - 	^ (self searchByDictionary: aString) ifNil: [aString]
> - !
>
> Item was removed:
> - ----- Method: String>>literalStringsDo: (in category '*gettext') -----
> - literalStringsDo: aBlock
> - 	"Assuming the receiver receiver is a literal, evaluate aBlock with all
> Strings (but not Symbols) within it."
> - 	aBlock value: self!
>
> Item was removed:
> - ----- Method: String>>translated (in category '*gettext') -----
> - translated
> - 	"answer the receiver translated to the default language"
> - 	| translation |
> - 	translation := self
> - 		translatedTo: LocaleID current
> - 		inDomain: (TextDomainManager domainOfMethod: thisContext sender
> method).
> - 	self == translation ifTrue: [^self translatedInAllDomains].
> - 	^translation!
>
> Item was removed:
> - ----- Method: String>>translatedIfCorresponds (in category '*gettext')
> -----
> - translatedIfCorresponds
> - 	"answer the receiver translated to the default language only if
> - 	the receiver begins and ends with an underscore (_)"
> - 	^ ('_*_' match: self)
> - 		ifTrue: [(self copyFrom: 2 to: self size - 1) translated]
> - 		ifFalse: [self]!
>
> Item was removed:
> - ----- Method: String>>translatedInAllDomains (in category '*gettext')
> -----
> - translatedInAllDomains
> - 	| translation |
> - 	"Transcript show: self printString, ' translatedInAllDomains'; cr."
> - 	TextDomainManager allKnownDomains do: [:domain |
> - 		translation := self translatedTo: LocaleID current inDomain: domain.
> - 		self = translation ifFalse: [^translation]
> - 	].
> - 	^self!
>
> Item was removed:
> - ----- Method: String>>translatedInAnyDomain (in category '*gettext')
> -----
> - translatedInAnyDomain
> - 	| translation |
> - 	Transcript show: self printString, ' translatedInAnyDomain'; cr.
> - 	TextDomainManager allKnownDomains do: [:domain |
> - 		translation := self translatedInDomain: domain.
> - 		self = translation ifFalse: [^translation]].
> - 	^self!
>
> Item was removed:
> - ----- Method: String>>translatedInDomain: (in category '*gettext') -----
> - translatedInDomain: aDomainName
> - 	| translation |
> - 	translation := self translatedTo: LocaleID current inDomain:
> aDomainName.
> - 	self == translation ifTrue: [^self translatedInAllDomains].
> - 	^translation
> - !
>
> Item was removed:
> - ----- Method: String>>translatedInDomain:or: (in category '*gettext')
> -----
> - translatedInDomain: aDomainName or: anotherDomainName
> - 	| translation |
> - 	translation := self translatedTo: LocaleID current inDomain:
> aDomainName.
> - 	self == translation ifTrue: [^self translatedInDomain:
> anotherDomainName].
> - 	^translation
> - !
>
> Item was removed:
> - ----- Method: String>>translatedNoop (in category '*gettext') -----
> - translatedNoop
> - 	"This is correspondence gettext_noop() in gettext."
> - 	^ self!
>
> Item was removed:
> - ----- Method: String>>translatedTo: (in category '*gettext') -----
> - translatedTo: localeID
> - 	"answer the receiver translated to the given locale id"
> - 	^ self translatedTo: localeID inDomain: (TextDomainManager
> domainOfMethod: thisContext sender method).!
>
> Item was removed:
> - ----- Method: String>>translatedTo:inDomain: (in category '*gettext')
> -----
> - translatedTo: localeID inDomain: aDomainName
> - 	"answer the receiver translated to the given locale id in the
> textdomain"
> -
> - 	^ NaturalLanguageTranslator translate: self
> - 								toLocaleID: localeID
> - 								inDomain:  aDomainName!
>
> Item was removed:
> - Object subclass: #TextDomainManager
> - 	instanceVariableNames: ''
> - 	classVariableNames: 'ClassCategories Classes DefaultDomain DomainInfos
> LoneClasses Packages'
> - 	poolDictionaries: ''
> - 	category: 'GetText-Localization'!
> - TextDomainManager class
> - 	instanceVariableNames: 'defaultDomain'!
> -
> - !TextDomainManager commentStamp: 'fbs 5/12/2013 13:04' prior: 0!
> - I manage mapping from class category to textdomain.
> -
> - Class variables:
> -  ClassCategories	IdentityDictionary -- classCategory -> domainName
> -  Classes			IdentityDictionary -- class name (a Symbol) -> domainName   (a
> cache only!!)
> -  DefaultDomain	String -- the default domain name
> -  DomainInfos		Dictionary -- domainName -> a TextDomainInfo
> -  LoneClasses		IdentityDictionary -- class name (a Symbol) -> domainName.
> For classes whose entire category are not all in the same domain (BookMorph
> and QuickGuideMorph)
> -
> - TextDomainManager registerCategoryPrefix: 'DrGeoII' domain: 'DrGeoII'.
> - TextDomainManager unregisterDomain: 'DrGeoII'.
> -
> - TextDomainManager registerClass: #QuickGuideMorph domain: 'quickguides'.
> - TextDomainManager registerClass: #QuickGuideHolderMorph  domain:
> 'quickguides'.
> - !
> - TextDomainManager class
> - 	instanceVariableNames: 'defaultDomain'!
>
> Item was removed:
> - ----- Method: TextDomainManager class>>allKnownDomains (in category
> 'accessing') -----
> - allKnownDomains
> - 	"Every package has its own text domain now so it's not necessary to keep
> a registry of all domains, we can simply return all the packages in the
> image.
> - 	PROBLEM: If a package doesn't contain translations, it won't have a mo
> file but the GetTextTranslator will try to load it anyway. This happens when
> we switch languages. So far I tested it briefly and it seems to work..."
> - 	^PackageOrganizer default packageNames , {'Etoys-Tiles'}!
>
> Item was removed:
> - ----- Method: TextDomainManager class>>allMethodsWithTranslations (in
> category 'accessing') -----
> - allMethodsWithTranslations
> - 	"Look for #translated calls"
> - 	| methodsWithTranslations |
> - 	methodsWithTranslations := TranslatedReceiverFinder new
> stringReceiversWithContext: #translated.
> - 	methodsWithTranslations := methodsWithTranslations ,
> - 		(TranslatedReceiverFinder new stringReceiversWithContext:
> #translatedNoop).
> -
> - 	methodsWithTranslations := methodsWithTranslations collect: [:each | each
> key compiledMethod].
> -
> - 	"Look for Etoys tiles and vocabularies"
> - 	methodsWithTranslations := methodsWithTranslations , (EToyVocabulary
> allPhrasesWithContextToTranslate collect: [:r |
> - 		(MethodReference new setStandardClass: r second methodSymbol: r third)
> compiledMethod]).
> -
> - 	^methodsWithTranslations!
>
> Item was removed:
> - ----- Method: TextDomainManager class>>cleanUp: (in category 'private')
> -----
> - cleanUp: aggressive
> - 	aggressive ifTrue: [self clearAllDomains].!
>
> Item was removed:
> - ----- Method: TextDomainManager class>>clearAllDomains (in category
> 'private') -----
> - clearAllDomains
> - 	"TextDomainManager clearAllDomains"
> - 	self systemNavigation allBehaviorsDo:
> - 		[:b|
> - 		b selectorsAndMethodsDo:
> - 			[:s :m |
> - 			m removeProperty: self textDomainProperty ifAbsent: []]]!
>
> Item was removed:
> - ----- Method: TextDomainManager class>>defaultDomain (in category
> 'accessing') -----
> - defaultDomain
> - 	"I'm not sure we still need a default domain. AFAIK the default domain
> will only be used when no domain is found. In that case, wouldn't it be
> better to just look for a translation in all domains?"
> - 	^defaultDomain!
>
> Item was removed:
> - ----- Method: TextDomainManager class>>defaultDomain: (in category
> 'accessing') -----
> - defaultDomain: aDomainName
> - 	defaultDomain := aDomainName!
>
> Item was removed:
> - ----- Method: TextDomainManager class>>domainForClass: (in category
> 'accessing') -----
> - domainForClass: aClass
> - 	^'etoys'!
>
> Item was removed:
> - ----- Method: TextDomainManager class>>domainForPackage: (in category
> 'accessing') -----
> - domainForPackage: aPackageInfo
> - 	"Package names and text domains are synonyms now"
> - 	^aPackageInfo name!
>
> Item was removed:
> - ----- Method: TextDomainManager class>>domainOfMethod: (in category
> 'accessing') -----
> - domainOfMethod: aCompiledMethod
> - 	^ aCompiledMethod
> - 		propertyValueAt: self textDomainProperty
> - 		ifAbsent: [self updateDomainOfMethod: aCompiledMethod] !
>
> Item was removed:
> - ----- Method: TextDomainManager class>>initialize (in category 'class
> initialization') -----
> - initialize
> - 	"	TextDomainManager initialize	"
> - 	self defaultDomain: 'Etoys'!
>
> Item was removed:
> - ----- Method: TextDomainManager class>>textDomainProperty (in category
> 'private') -----
> - textDomainProperty
> - 	^#textDomain!
>
> Item was removed:
> - ----- Method: TextDomainManager
> class>>updateDomainOfAllMethodsWithTranslations (in category 'private')
> -----
> - updateDomainOfAllMethodsWithTranslations
> - 	self allMethodsWithTranslations do: [:each |
> - 		self updateDomainOfMethod: each]!
>
> Item was removed:
> - ----- Method: TextDomainManager class>>updateDomainOfMethod: (in category
> 'private') -----
> - updateDomainOfMethod: aCompiledMethod
> - 	"First it looks for the package of the method reference (using
> - 	the PackageOrganizer: deadly slow). If the method doesn't
> - 	belong to any package it uses the default domain. Finally it
> - 	stores the text domain of the method using a method
> - 	property, this way we gain performance the next time we
> - 	translate the same method because we avoid the use of
> - 	PackageOrganizer. Have I mentioned it is really slow? :)"
> - 	| package |
> - 	package := PackageOrganizer default
> - 				packageOfMethod: aCompiledMethod methodReference
> - 				ifNone: [].
> - 	^ aCompiledMethod
> - 		propertyValueAt: self textDomainProperty
> - 		put: (package isNil
> - 				ifTrue: [TextDomainManager defaultDomain]
> - 				ifFalse: [package name])!
>
> Item was removed:
> - Object subclass: #TranslatedReceiverFinder
> - 	instanceVariableNames: ''
> - 	classVariableNames: ''
> - 	poolDictionaries: ''
> - 	category: 'GetText-Editor'!
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder class>>browseNonLiteralReceivers
> (in category 'utilities') -----
> - browseNonLiteralReceivers
> - 	"TranslatedReceiverFinder browseNonLiteralReceivers"
> - 	SystemNavigation default
> - 		browseMessageList: self new nonLiteralReceivers  asSortedCollection
> - 		name: 'Non literal receivers of #translated'
> - 		autoSelect: 'translated'!
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder class>>makeJapaneseTranslationFile
> (in category 'as yet unclassified') -----
> - makeJapaneseTranslationFile
> - 	| t n |
> - 	NaturalLanguageTranslator initializeKnownPhrases.
> - 	t := TranslatedReceiverFinder new senders.
> - 	n := NaturalLanguageTranslator
> - 				localeID: (LocaleID isoLanguage: 'ja').
> - 	t
> - 		do: [:w |
> - 			NaturalLanguageTranslator registerPhrase: w.
> - 			self
> - 				at: w
> - 				ifPresent: [:k | n phrase: w translation: k]].
> - 	n saveToFileNamed: 'ja.translation'!
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>arraySearch:fromArray:addTo: (in
> category 'private') -----
> - arraySearch: aSymbol fromArray: anArray addTo: aCollection
> - 	"Find literals ahead of aSymbol from arrays in the method."
> - 	"BUG: it can handle just one occurrence"
> - 	"self new arraySearch: #hello fromArray: #(ignore (ignore detected
> - 	hello ignore)) addTo: Set new"
> - 	| index |
> - 	(index := anArray identityIndexOf: aSymbol) > 1
> - 		ifTrue: [aCollection add: (anArray at: index - 1) asString].
> - 	(anArray
> - 		select: [:each | each isMemberOf: Array])
> - 		do: [:each | self
> - 				arraySearch: aSymbol
> - 				fromArray: each
> - 				addTo: aCollection].
> - 	^ aCollection!
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>arraySearch:messageNode:addTo: (in
> category 'private') -----
> - arraySearch: aSymbol messageNode: aParseNode addTo: aCollection
> - 	"Find literals ahead of aSymbol from arrays in the method."
> - 	"self new arraySearch: #hello messageNode: (self
> - 	decompile: #arraySearch:messageNode:addTo:) addTo: Set new"
> - 	self flag: #(#ignore #detected #hello ).
> - 	((aParseNode isMemberOf: LiteralNode)
> - 			and: [aParseNode key isMemberOf: Array])
> - 		ifTrue: [self
> - 				arraySearch: aSymbol
> - 				fromArray: aParseNode key
> - 				addTo: aCollection].
> - 	(aParseNode notNil
> - 			and: [aParseNode isLeaf not])
> - 		ifTrue: [aParseNode getAllChildren
> - 				do: [:child | self
> - 						arraySearch: aSymbol
> - 						messageNode: child
> - 						addTo: aCollection]].
> - 	^ aCollection!
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>findWordsWith:in: (in category
> 'accessing') -----
> - findWordsWith: aSymbol in: aMethodReference
> - 	"Find words for translation with the symbol in a method. See
> - 	LanguageEditorTest >>testFindTranslatedWords"
> - 	"| message |
> - 	message := MethodReference new setStandardClass: Morph class
> - 	methodSymbol: #supplementaryPartsDescriptions.
> - 	self new findWordsWIth: #translatedNoop in: message"
> - 	| messages keywords aParseNode |
> - 	aParseNode := aMethodReference decompile.
> - 	"Find from string literal"
> - 	messages := Set new.
> - 	self
> - 		search: aSymbol
> - 		messageNode: aParseNode
> - 		addTo: messages.
> - 	keywords := OrderedCollection new.
> - 	messages
> - 		select: [:aMessageNode | aMessageNode receiver isMemberOf: LiteralNode]
> - 		thenDo: [:aMessageNode | aMessageNode receiver key
> - 				literalStringsDo: [:literal | keywords add: literal]].
> - 	"Find from array literal"
> - 	self
> - 		arraySearch: aSymbol
> - 		messageNode: aParseNode
> - 		addTo: keywords.
> - 	^ keywords!
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>nonLiteralReceivers (in category
> 'accessing') -----
> - nonLiteralReceivers
> - 	"self new nonLiteralReceivers"
> - 	| receivers |
> - 	"Answer method references of non literal senders of #translated"
> - 	^ (SystemNavigation default allCallsOn: #translated)
> - 		select: [:message |
> - 			receivers := OrderedCollection new.
> - 			self search: #translated messageNode: message decompile addTo:
> receivers.
> - 			receivers
> - 				anySatisfy: [:each | (each receiver isMemberOf: LiteralNode) not]]!
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>search:messageNode:addTo: (in
> category 'private') -----
> - search: aSymbol messageNode: aParseNode addTo: aCollection
> - 	"self new search: #translated messageNode: (Project decompile:
> #updateLocaleDependentsWithPreviousSupplies:gently:) addTo:
> OrderedCollection new"
> -
> - 	((aParseNode isMemberOf: MessageNode)
> - 			and: [(aParseNode selector isMemberOf: SelectorNode)
> - 					and: [aParseNode selector key = aSymbol]])
> - 		ifTrue: [aCollection add: aParseNode].
> - 	(aParseNode notNil
> - 			and: [aParseNode isLeaf not])
> - 		ifTrue: [aParseNode getAllChildren
> - 				do: [:child | self
> - 						search: aSymbol
> - 						messageNode: child
> - 						addTo: aCollection]].
> - 	^ aCollection!
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>searchBlockNode:addTo: (in
> category 'as yet unclassified') -----
> - searchBlockNode: aBlockNode addTo: aCollection
> -
> - 	aBlockNode statements do: [:e |
> - 		(e isMemberOf: MessageNode) ifTrue: [self searchMessageNode: e addTo:
> aCollection].
> - 		(e isMemberOf: ReturnNode) ifTrue: [self searchReturnNode: e addTo:
> aCollection].
> - 	].
> - !
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>searchMessageNode:addTo: (in
> category 'as yet unclassified') -----
> - searchMessageNode: aMessageNode addTo: aCollection
> -
> - 	((aMessageNode receiver isMemberOf: LiteralNode) and: [(aMessageNode
> selector isMemberOf: SelectorNode) and: [aMessageNode selector key =
> #translated]]) ifTrue: [
> - 		aCollection add: aMessageNode receiver key.
> - 	].
> -
> - 	(aMessageNode receiver isMemberOf: BlockNode) ifTrue: [self
> searchBlockNode: aMessageNode receiver addTo: aCollection].
> - 	(aMessageNode receiver isMemberOf: MessageNode) ifTrue: [self
> searchMessageNode: aMessageNode receiver addTo: aCollection].
> - 	(aMessageNode receiver isMemberOf: ReturnNode) ifTrue: [self
> searchReturnNode: aMessageNode receiver addTo: aCollection].
> -
> - 	aMessageNode arguments do: [:a |
> - 		(a isMemberOf: BlockNode) ifTrue: [self searchBlockNode: a addTo:
> aCollection].
> - 		(a isMemberOf: MessageNode) ifTrue: [self searchMessageNode: a addTo:
> aCollection].
> - 		(a isMemberOf: ReturnNode) ifTrue: [self searchReturnNode: a addTo:
> aCollection].
> - 	].
> - !
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>searchMethodNode:addTo: (in
> category 'as yet unclassified') -----
> - searchMethodNode: aMethodNode addTo: aCollection
> -
> - 	(aMethodNode block isMemberOf: BlockNode) ifTrue: [self searchBlockNode:
> aMethodNode block addTo: aCollection].
> - 	(aMethodNode block isMemberOf: MessageNode) ifTrue: [self
> searchMessageNode: aMethodNode block addTo: aCollection].
> - 	(aMethodNode block isMemberOf: ReturnNode) ifTrue: [self
> searchReturnNode: aMethodNode block addTo: aCollection].
> - !
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>searchReturnNode:addTo: (in
> category 'as yet unclassified') -----
> - searchReturnNode: aReturnNode addTo: aCollection
> -
> - 	(aReturnNode expr isMemberOf: BlockNode) ifTrue: [self searchBlockNode:
> aReturnNode expr addTo: aCollection].
> - 	(aReturnNode expr isMemberOf: MessageNode) ifTrue: [self
> searchMessageNode: aReturnNode expr addTo: aCollection].
> - !
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>senders (in category 'as yet
> unclassified') -----
> - senders
> -
> - 	| m o |
> - 	m := SystemNavigation default allCallsOn: #translated.
> - 	m := m collect: [:e |
> - 		e classIsMeta ifTrue: [
> - 			(Smalltalk at: e classSymbol) class decompile: e methodSymbol.
> - 		] ifFalse: [
> - 			(Smalltalk at: e classSymbol) decompile: e methodSymbol.
> - 		]
> - 	].
> -
> - 	o := OrderedCollection new.
> - 	m do: [:e | self searchMethodNode: e addTo: o].
> - 	^ o sort
> - !
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>stringReceivers (in category
> 'accessing') -----
> - stringReceivers
> - 	"TranslatedReceiverFinder new stringReceivers"
> - 	| stringReceivers messages |
> - 	messages := Set new.
> - 	(SystemNavigation default allCallsOn: #translated)
> - 		do: [:message | self search: #translated messageNode: message decompile
> addTo: messages].
> - 	stringReceivers := messages
> - 				select: [:each | each receiver isMemberOf: LiteralNode]
> - 				thenCollect: [:each | each receiver key].
> - 	^ stringReceivers asArray sort!
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>stringReceiversWithContext (in
> category 'accessing') -----
> - stringReceiversWithContext
> - 	| mrs results rr cls mn t o |
> - 	mrs := SystemNavigation default allCallsOn: #translated.
> - 	results := OrderedCollection new.
> - 	mrs do: [:mr |
> - 		rr := OrderedCollection new.
> - 		cls := Smalltalk at: mr classSymbol.
> - 		rr add: cls category.
> - 		rr add: mr classSymbol.
> - 		rr add: mr methodSymbol.
> - 		mr classIsMeta ifTrue: [
> - 			mn :=  cls class decompile: mr methodSymbol.
> - 		] ifFalse: [
> - 			mn := cls decompile: mr methodSymbol.
> - 		].
> - 		o := OrderedCollection new.
> - 		t := Set new.
> - 		self searchMessageNode: mn addTo: t.
> - 		t do: [ :te |
> - 			(te receiver isMemberOf: LiteralNode) ifTrue: [
> - 			    o add: te receiver key.
> - 			].
> - 		].
> - 		o ifNotEmpty: [
> - 			rr add: o.
> - 			results add: rr.
> - 		].
> - 	].
> - 	^ results.
> -
> - !
>
> Item was removed:
> - ----- Method: TranslatedReceiverFinder>>stringReceiversWithContext: (in
> category 'accessing') -----
> - stringReceiversWithContext: aSymbol
> - 	"Find string receivers for a symbol.
> - 	Answer a collection of aMethodReference -> {keyword. keyword...}"
> - 	"self new stringReceiversWithContext: #translated"
> - 	| keywords methodReferences |
> - 	methodReferences := SystemNavigation default allCallsOn: aSymbol.
> - 	^ methodReferences inject: OrderedCollection new into: [:list :next |
> - 		keywords := self findWordsWith: aSymbol in: next.
> - 		keywords
> - 			ifNotEmpty: [list add: next -> keywords].
> - 		list]
> - !
>
>
>


More information about the Squeak-dev mailing list