diff options
Diffstat (limited to 'tools/grit/grit/clique.py')
-rw-r--r-- | tools/grit/grit/clique.py | 116 |
1 files changed, 58 insertions, 58 deletions
diff --git a/tools/grit/grit/clique.py b/tools/grit/grit/clique.py index 2f6fe40..52a50c6 100644 --- a/tools/grit/grit/clique.py +++ b/tools/grit/grit/clique.py @@ -19,7 +19,7 @@ class UberClique(object): '''A factory (NOT a singleton factory) for making cliques. It has several methods for working with the cliques created using the factory. ''' - + def __init__(self): # A map from message ID to list of cliques whose source messages have # that ID. This will contain all cliques created using this factory. @@ -27,14 +27,14 @@ class UberClique(object): # same translateable portion and placeholder names, but occur in different # places in the resource tree. self.cliques_ = {} - + # A map of clique IDs to list of languages to indicate translations where we # fell back to English. self.fallback_translations_ = {} - + # A map of clique IDs to list of languages to indicate missing translations. self.missing_translations_ = {} - + def _AddMissingTranslation(self, lang, clique, is_error): tl = self.fallback_translations_ if is_error: @@ -44,10 +44,10 @@ class UberClique(object): tl[id] = {} if lang not in tl[id]: tl[id][lang] = 1 - + def HasMissingTranslations(self): return len(self.missing_translations_) > 0 - + def MissingTranslationsReport(self): '''Returns a string suitable for printing to report missing and fallback translations to the user. @@ -78,13 +78,13 @@ class UberClique(object): def MakeClique(self, message, translateable=True): '''Create a new clique initialized with a message. - + Args: message: tclib.Message() translateable: True | False ''' clique = MessageClique(self, message, translateable) - + # Enable others to find this clique by its message ID if message.GetId() in self.cliques_: presentable_text = clique.GetMessage().GetPresentableContent() @@ -93,17 +93,17 @@ class UberClique(object): self.cliques_[message.GetId()].append(clique) else: self.cliques_[message.GetId()] = [clique] - + return clique def FindCliqueAndAddTranslation(self, translation, language): '''Adds the specified translation to the clique with the source message it is a translation of. - + Args: translation: tclib.Translation() language: 'en' | 'fr' ... - + Return: True if the source message was found, otherwise false. ''' @@ -113,7 +113,7 @@ class UberClique(object): return True else: return False - + def BestClique(self, id): '''Returns the "best" clique from a list of cliques. All the cliques must have the same ID. The "best" clique is chosen in the following @@ -127,14 +127,14 @@ class UberClique(object): for clique in clique_list: if not clique_to_ret: clique_to_ret = clique - + description = clique.GetMessage().GetDescription() if description and len(description) > 0: clique_to_ret = clique if not description.startswith('ID:'): break # this is the preferred case so we exit right away return clique_to_ret - + def BestCliquePerId(self): '''Iterates over the list of all cliques and returns the best clique for each ID. This will be the first clique with a source message that has a @@ -143,7 +143,7 @@ class UberClique(object): ''' for id in self.cliques_: yield self.BestClique(id) - + def BestCliqueByOriginalText(self, text, meaning): '''Finds the "best" (as in BestClique()) clique that has original text 'text' and meaning 'meaning'. Returns None if there is no such clique. @@ -160,7 +160,7 @@ class UberClique(object): '''Returns a list of all defined message IDs. ''' return self.cliques_.keys() - + def AllCliques(self): '''Iterates over all cliques. Note that this can return multiple cliques with the same ID. @@ -168,14 +168,14 @@ class UberClique(object): for cliques in self.cliques_.values(): for c in cliques: yield c - + def GenerateXtbParserCallback(self, lang, debug=False): '''Creates a callback function as required by grit.xtb_reader.Parse(). This callback will create Translation objects for each message from the XTB that exists in this uberclique, and add them as translations for the relevant cliques. The callback will add translations to the language specified by 'lang' - + Args: lang: 'fr' debug: True | False @@ -184,13 +184,13 @@ class UberClique(object): if id not in self.cliques_: if debug: print "Ignoring translation #%s" % id return - + if debug: print "Adding translation #%s" % id - + # We fetch placeholder information from the original message (the XTB file # only contains placeholder names). original_msg = self.BestClique(id).GetMessage() - + translation = tclib.Translation(id=id) for is_ph,text in structure: if not is_ph: @@ -215,27 +215,27 @@ class CustomType(object): '''A base class you should implement if you wish to specify a custom type for a message clique (i.e. custom validation and optional modification of translations).''' - + def Validate(self, message): '''Returns true if the message (a tclib.Message object) is valid, otherwise false. ''' raise NotImplementedError() - + def ValidateAndModify(self, lang, translation): '''Returns true if the translation (a tclib.Translation object) is valid, otherwise false. The language is also passed in. This method may modify the translation that is passed in, if it so wishes. ''' raise NotImplementedError() - + def ModifyTextPart(self, lang, text): '''If you call ModifyEachTextPart, it will turn around and call this method for each text part of the translation. You should return the modified version of the text, or just the original text to not change anything. ''' raise NotImplementedError() - + def ModifyEachTextPart(self, lang, translation): '''Call this to easily modify one or more of the textual parts of a translation. It will call ModifyTextPart for each part of the @@ -271,18 +271,18 @@ class OneOffCustomType(CustomType): class MessageClique(object): '''A message along with all of its translations. Also code to bring translations together with their original message.''' - + # change this to the language code of Messages you add to cliques_. # TODO(joi) Actually change this based on the <grit> node's source language source_language = 'en' - + # A constant translation we use when asked for a translation into the # special language constants.CONSTANT_LANGUAGE. CONSTANT_TRANSLATION = tclib.Translation(text='TTTTTT') - + def __init__(self, uber_clique, message, translateable=True, custom_type=None): '''Create a new clique initialized with just a message. - + Args: uber_clique: Our uber-clique (collection of cliques) message: tclib.Message() @@ -305,21 +305,21 @@ class MessageClique(object): # be used to validate the original message and translations thereof, and # will also get a chance to modify translations of the message. self.SetCustomType(custom_type) - + def GetMessage(self): '''Retrieves the tclib.Message that is the source for this clique.''' return self.clique[MessageClique.source_language] - + def GetId(self): '''Retrieves the message ID of the messages in this clique.''' return self.GetMessage().GetId() - + def IsTranslateable(self): return self.translateable - + def AddToShortcutGroup(self, group): self.shortcut_groups.append(group) - + def SetCustomType(self, custom_type): '''Makes this clique use custom_type for validating messages and translations, and optionally modifying translations. @@ -327,53 +327,53 @@ class MessageClique(object): self.custom_type = custom_type if custom_type and not custom_type.Validate(self.GetMessage()): raise exception.InvalidMessage(self.GetMessage().GetRealContent()) - + def MessageForLanguage(self, lang, pseudo_if_no_match=True, fallback_to_english=False): '''Returns the message/translation for the specified language, providing a pseudotranslation if there is no available translation and a pseudo- translation is requested. - + The translation of any message whatsoever in the special language 'x_constant' is the message "TTTTTT". - + Args: lang: 'en' pseudo_if_no_match: True fallback_to_english: False - + Return: tclib.BaseMessage ''' if not self.translateable: return self.GetMessage() - + if lang == constants.CONSTANT_LANGUAGE: return self.CONSTANT_TRANSLATION - + for msglang in self.clique.keys(): if lang == msglang: return self.clique[msglang] - + if fallback_to_english: self.uber_clique._AddMissingTranslation(lang, self, is_error=False) return self.GetMessage() - + # If we're not supposed to generate pseudotranslations, we add an error # report to a list of errors, then fail at a higher level, so that we # get a list of all messages that are missing translations. if not pseudo_if_no_match: self.uber_clique._AddMissingTranslation(lang, self, is_error=True) - + return pseudo.PseudoMessage(self.GetMessage()) def AllMessagesThatMatch(self, lang_re, include_pseudo = True): '''Returns a map of all messages that match 'lang', including the pseudo translation if requested. - + Args: lang_re: re.compile('fr|en') include_pseudo: True - + Return: { 'en' : tclib.Message, 'fr' : tclib.Translation, @@ -381,27 +381,27 @@ class MessageClique(object): ''' if not self.translateable: return [self.GetMessage()] - + matches = {} for msglang in self.clique: if lang_re.match(msglang): matches[msglang] = self.clique[msglang] - + if include_pseudo: matches[pseudo.PSEUDO_LANG] = pseudo.PseudoMessage(self.GetMessage()) - + return matches - + def AddTranslation(self, translation, language): '''Add a translation to this clique. The translation must have the same ID as the message that is the source for this clique. - + If this clique is not translateable, the function just returns. - + Args: translation: tclib.Translation() language: 'en' - + Throws: grit.exception.InvalidTranslation if the translation you're trying to add doesn't have the same message ID as the source message of this clique. @@ -411,9 +411,9 @@ class MessageClique(object): if translation.GetId() != self.GetId(): raise exception.InvalidTranslation( 'Msg ID %s, transl ID %s' % (self.GetId(), translation.GetId())) - + assert not language in self.clique - + # Because two messages can differ in the original content of their # placeholders yet share the same ID (because they are otherwise the # same), the translation we are getting may have different original @@ -424,20 +424,20 @@ class MessageClique(object): # # See grit.clique_unittest.MessageCliqueUnittest.testSemiIdenticalCliques # for a concrete explanation of why this is necessary. - + original = self.MessageForLanguage(self.source_language, False) if len(original.GetPlaceholders()) != len(translation.GetPlaceholders()): print ("ERROR: '%s' translation of message id %s does not match" % (language, translation.GetId())) assert False - + transl_msg = tclib.Translation(id=self.GetId(), text=translation.GetPresentableContent(), placeholders=original.GetPlaceholders()) - + if self.custom_type and not self.custom_type.ValidateAndModify(language, transl_msg): print "WARNING: %s translation failed validation: %s" % ( language, transl_msg.GetId()) - + self.clique[language] = transl_msg |