Index: grit/tclib.py |
=================================================================== |
--- grit/tclib.py (revision 0) |
+++ grit/tclib.py (revision 0) |
@@ -0,0 +1,216 @@ |
+#!/usr/bin/python2.4 |
+# Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+'''Adaptation of the extern.tclib classes for our needs. |
+''' |
+ |
+ |
+import re |
+import types |
+ |
+from grit import exception |
+import grit.extern.tclib |
+ |
+def Identity(i): |
+ return i |
+ |
+ |
+class BaseMessage(object): |
+ '''Base class with methods shared by Message and Translation. |
+ ''' |
+ |
+ def __init__(self, text='', placeholders=[], description='', meaning=''): |
+ self.parts = [] |
+ self.placeholders = [] |
+ self.description = description |
+ self.meaning = meaning |
+ self.dirty = True # True if self.id is (or might be) wrong |
+ self.id = 0 |
+ |
+ if text != '': |
+ if not placeholders or placeholders == []: |
+ self.AppendText(text) |
+ else: |
+ tag_map = {} |
+ for placeholder in placeholders: |
+ tag_map[placeholder.GetPresentation()] = [placeholder, 0] |
+ tag_re = '(' + '|'.join(tag_map.keys()) + ')' |
+ # This creates a regexp like '(TAG1|TAG2|TAG3)' |
+ chunked_text = re.split(tag_re, text) |
+ for chunk in chunked_text: |
+ if chunk: # ignore empty chunk |
+ if tag_map.has_key(chunk): |
+ self.AppendPlaceholder(tag_map[chunk][0]) |
+ tag_map[chunk][1] += 1 # increase placeholder use count |
+ else: |
+ self.AppendText(chunk) |
+ for key in tag_map.keys(): |
+ assert tag_map[key][1] != 0 |
+ |
+ def GetRealContent(self, escaping_function=Identity): |
+ '''Returns the original content, i.e. what your application and users |
+ will see. |
+ |
+ Specify a function to escape each translateable bit, if you like. |
+ ''' |
+ bits = [] |
+ for item in self.parts: |
+ if isinstance(item, types.StringTypes): |
+ bits.append(escaping_function(item)) |
+ else: |
+ bits.append(item.GetOriginal()) |
+ return ''.join(bits) |
+ |
+ def GetPresentableContent(self): |
+ presentable_content = [] |
+ for part in self.parts: |
+ if isinstance(part, Placeholder): |
+ presentable_content.append(part.GetPresentation()) |
+ else: |
+ presentable_content.append(part) |
+ return ''.join(presentable_content) |
+ |
+ def AppendPlaceholder(self, placeholder): |
+ assert isinstance(placeholder, Placeholder) |
+ dup = False |
+ for other in self.GetPlaceholders(): |
+ if other.presentation == placeholder.presentation: |
+ assert other.original == placeholder.original |
+ dup = True |
+ |
+ if not dup: |
+ self.placeholders.append(placeholder) |
+ self.parts.append(placeholder) |
+ self.dirty = True |
+ |
+ def AppendText(self, text): |
+ assert isinstance(text, types.StringTypes) |
+ assert text != '' |
+ |
+ self.parts.append(text) |
+ self.dirty = True |
+ |
+ def GetContent(self): |
+ '''Returns the parts of the message. You may modify parts if you wish. |
+ Note that you must not call GetId() on this object until you have finished |
+ modifying the contents. |
+ ''' |
+ self.dirty = True # user might modify content |
+ return self.parts |
+ |
+ def GetDescription(self): |
+ return self.description |
+ |
+ def SetDescription(self, description): |
+ self.description = description |
+ |
+ def GetMeaning(self): |
+ return self.meaning |
+ |
+ def GetId(self): |
+ if self.dirty: |
+ self.id = self.GenerateId() |
+ self.dirty = False |
+ return self.id |
+ |
+ def GenerateId(self): |
+ # Must use a UTF-8 encoded version of the presentable content, along with |
+ # the meaning attribute, to match the TC. |
+ return grit.extern.tclib.GenerateMessageId( |
+ self.GetPresentableContent().encode('utf-8'), self.meaning) |
+ |
+ def GetPlaceholders(self): |
+ return self.placeholders |
+ |
+ def FillTclibBaseMessage(self, msg): |
+ msg.SetDescription(self.description.encode('utf-8')) |
+ |
+ for part in self.parts: |
+ if isinstance(part, Placeholder): |
+ ph = grit.extern.tclib.Placeholder( |
+ part.presentation.encode('utf-8'), |
+ part.original.encode('utf-8'), |
+ part.example.encode('utf-8')) |
+ msg.AppendPlaceholder(ph) |
+ else: |
+ msg.AppendText(part.encode('utf-8')) |
+ |
+ |
+class Message(BaseMessage): |
+ '''A message.''' |
+ |
+ def __init__(self, text='', placeholders=[], description='', meaning='', |
+ assigned_id=None): |
+ BaseMessage.__init__(self, text, placeholders, description, meaning) |
+ self.assigned_id = assigned_id |
+ |
+ def ToTclibMessage(self): |
+ msg = grit.extern.tclib.Message('utf-8', meaning=self.meaning) |
+ self.FillTclibBaseMessage(msg) |
+ return msg |
+ |
+ def GetId(self): |
+ '''Use the assigned id if we have one.''' |
+ if self.assigned_id: |
+ return self.assigned_id |
+ |
+ return BaseMessage.GetId(self) |
+ |
+ |
+class Translation(BaseMessage): |
+ '''A translation.''' |
+ |
+ def __init__(self, text='', id='', placeholders=[], description='', meaning=''): |
+ BaseMessage.__init__(self, text, placeholders, description, meaning) |
+ self.id = id |
+ |
+ def GetId(self): |
+ assert id != '', "ID has not been set." |
+ return self.id |
+ |
+ def SetId(self, id): |
+ self.id = id |
+ |
+ def ToTclibMessage(self): |
+ msg = grit.extern.tclib.Message( |
+ 'utf-8', id=self.id, meaning=self.meaning) |
+ self.FillTclibBaseMessage(msg) |
+ return msg |
+ |
+ |
+class Placeholder(grit.extern.tclib.Placeholder): |
+ '''Modifies constructor to accept a Unicode string |
+ ''' |
+ |
+ # Must match placeholder presentation names |
+ _NAME_RE = re.compile('^[A-Za-z0-9_]+$') |
+ |
+ def __init__(self, presentation, original, example): |
+ '''Creates a new placeholder. |
+ |
+ Args: |
+ presentation: 'USERNAME' |
+ original: '%s' |
+ example: 'Joi' |
+ ''' |
+ assert presentation != '' |
+ assert original != '' |
+ assert example != '' |
+ if not self._NAME_RE.match(presentation): |
+ raise exception.InvalidPlaceholderName(presentation) |
+ self.presentation = presentation |
+ self.original = original |
+ self.example = example |
+ |
+ def GetPresentation(self): |
+ return self.presentation |
+ |
+ def GetOriginal(self): |
+ return self.original |
+ |
+ def GetExample(self): |
+ return self.example |
+ |
+ |
Property changes on: grit/tclib.py |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |