| Index: grit/node/message.py | 
| diff --git a/grit/node/message.py b/grit/node/message.py | 
| index bb0dd4d816194de8f21d74e93cb4f4492cda2a12..1f63bdada18637e27a62e349490605925a56ad0d 100644 | 
| --- a/grit/node/message.py | 
| +++ b/grit/node/message.py | 
| @@ -56,9 +56,10 @@ class MessageNode(base.ContentNode): | 
| def _IsValidAttribute(self, name, value): | 
| if name not in ['name', 'offset', 'translateable', 'desc', 'meaning', | 
| 'internal_comment', 'shortcut_groups', 'custom_type', | 
| -                    'validation_expr', 'use_name_for_id']: | 
| +                    'validation_expr', 'use_name_for_id', 'sub_variable']: | 
| return False | 
| -    if name == 'translateable' and value not in ['true', 'false']: | 
| +    if (name in ('translateable', 'sub_variable') and | 
| +        value not in ['true', 'false']): | 
| return False | 
| return True | 
|  | 
| @@ -67,14 +68,15 @@ class MessageNode(base.ContentNode): | 
|  | 
| def DefaultAttributes(self): | 
| return { | 
| -      'translateable' : 'true', | 
| +      'custom_type' : '', | 
| 'desc' : '', | 
| -      'meaning' : '', | 
| 'internal_comment' : '', | 
| +      'meaning' : '', | 
| 'shortcut_groups' : '', | 
| -      'custom_type' : '', | 
| -      'validation_expr' : '', | 
| +      'sub_variable' : 'false', | 
| +      'translateable' : 'true', | 
| 'use_name_for_id' : 'false', | 
| +      'validation_expr' : '', | 
| } | 
|  | 
| def GetTextualIds(self): | 
| @@ -158,6 +160,14 @@ class MessageNode(base.ContentNode): | 
| description=description_or_id, | 
| meaning=self.attrs['meaning'], | 
| assigned_id=assigned_id) | 
| +    self.InstallMessage(message) | 
| + | 
| +  def InstallMessage(self, message): | 
| +    '''Sets this node's clique from a tclib.Message instance. | 
| + | 
| +    Args: | 
| +      message: A tclib.Message. | 
| +    ''' | 
| self.clique = self.UberClique().MakeClique(message, self.IsTranslateable()) | 
| for group in self.shortcut_groups_: | 
| self.clique.AddToShortcutGroup(group) | 
| @@ -168,6 +178,16 @@ class MessageNode(base.ContentNode): | 
| self.clique.SetCustomType( | 
| clique.OneOffCustomType(self.attrs['validation_expr'])) | 
|  | 
| +  def SubstituteMessages(self, substituter): | 
| +    '''Applies substitution to this message. | 
| + | 
| +    Args: | 
| +      substituter: a grit.util.Substituter object. | 
| +    ''' | 
| +    message = substituter.SubstituteMessage(self.clique.GetMessage()) | 
| +    if message is not self.clique.GetMessage(): | 
| +      self.InstallMessage(message) | 
| + | 
| def GetCliques(self): | 
| if self.clique: | 
| return [self.clique] | 
| @@ -190,6 +210,10 @@ class MessageNode(base.ContentNode): | 
| else: | 
| return self.attrs['offset'] | 
|  | 
| +  def ExpandVariables(self): | 
| +    '''We always expand variables on Messages.''' | 
| +    return True | 
| + | 
| def GetDataPackPair(self, lang, encoding): | 
| '''Returns a (id, string) pair that represents the string id and the string | 
| in utf8.  This is used to generate the data pack data file. | 
|  |