| 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
|
|
|
|
|