Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: grit/tclib.py

Issue 7994004: Initial source commit to grit-i18n project. (Closed) Base URL: http://grit-i18n.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « grit/shortcuts_unittests.py ('k') | grit/tclib_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 #!/usr/bin/python2.4
2 # Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 '''Adaptation of the extern.tclib classes for our needs.
7 '''
8
9
10 import re
11 import types
12
13 from grit import exception
14 import grit.extern.tclib
15
16 def Identity(i):
17 return i
18
19
20 class BaseMessage(object):
21 '''Base class with methods shared by Message and Translation.
22 '''
23
24 def __init__(self, text='', placeholders=[], description='', meaning=''):
25 self.parts = []
26 self.placeholders = []
27 self.description = description
28 self.meaning = meaning
29 self.dirty = True # True if self.id is (or might be) wrong
30 self.id = 0
31
32 if text != '':
33 if not placeholders or placeholders == []:
34 self.AppendText(text)
35 else:
36 tag_map = {}
37 for placeholder in placeholders:
38 tag_map[placeholder.GetPresentation()] = [placeholder, 0]
39 tag_re = '(' + '|'.join(tag_map.keys()) + ')'
40 # This creates a regexp like '(TAG1|TAG2|TAG3)'
41 chunked_text = re.split(tag_re, text)
42 for chunk in chunked_text:
43 if chunk: # ignore empty chunk
44 if tag_map.has_key(chunk):
45 self.AppendPlaceholder(tag_map[chunk][0])
46 tag_map[chunk][1] += 1 # increase placeholder use count
47 else:
48 self.AppendText(chunk)
49 for key in tag_map.keys():
50 assert tag_map[key][1] != 0
51
52 def GetRealContent(self, escaping_function=Identity):
53 '''Returns the original content, i.e. what your application and users
54 will see.
55
56 Specify a function to escape each translateable bit, if you like.
57 '''
58 bits = []
59 for item in self.parts:
60 if isinstance(item, types.StringTypes):
61 bits.append(escaping_function(item))
62 else:
63 bits.append(item.GetOriginal())
64 return ''.join(bits)
65
66 def GetPresentableContent(self):
67 presentable_content = []
68 for part in self.parts:
69 if isinstance(part, Placeholder):
70 presentable_content.append(part.GetPresentation())
71 else:
72 presentable_content.append(part)
73 return ''.join(presentable_content)
74
75 def AppendPlaceholder(self, placeholder):
76 assert isinstance(placeholder, Placeholder)
77 dup = False
78 for other in self.GetPlaceholders():
79 if other.presentation == placeholder.presentation:
80 assert other.original == placeholder.original
81 dup = True
82
83 if not dup:
84 self.placeholders.append(placeholder)
85 self.parts.append(placeholder)
86 self.dirty = True
87
88 def AppendText(self, text):
89 assert isinstance(text, types.StringTypes)
90 assert text != ''
91
92 self.parts.append(text)
93 self.dirty = True
94
95 def GetContent(self):
96 '''Returns the parts of the message. You may modify parts if you wish.
97 Note that you must not call GetId() on this object until you have finished
98 modifying the contents.
99 '''
100 self.dirty = True # user might modify content
101 return self.parts
102
103 def GetDescription(self):
104 return self.description
105
106 def SetDescription(self, description):
107 self.description = description
108
109 def GetMeaning(self):
110 return self.meaning
111
112 def GetId(self):
113 if self.dirty:
114 self.id = self.GenerateId()
115 self.dirty = False
116 return self.id
117
118 def GenerateId(self):
119 # Must use a UTF-8 encoded version of the presentable content, along with
120 # the meaning attribute, to match the TC.
121 return grit.extern.tclib.GenerateMessageId(
122 self.GetPresentableContent().encode('utf-8'), self.meaning)
123
124 def GetPlaceholders(self):
125 return self.placeholders
126
127 def FillTclibBaseMessage(self, msg):
128 msg.SetDescription(self.description.encode('utf-8'))
129
130 for part in self.parts:
131 if isinstance(part, Placeholder):
132 ph = grit.extern.tclib.Placeholder(
133 part.presentation.encode('utf-8'),
134 part.original.encode('utf-8'),
135 part.example.encode('utf-8'))
136 msg.AppendPlaceholder(ph)
137 else:
138 msg.AppendText(part.encode('utf-8'))
139
140
141 class Message(BaseMessage):
142 '''A message.'''
143
144 def __init__(self, text='', placeholders=[], description='', meaning='',
145 assigned_id=None):
146 BaseMessage.__init__(self, text, placeholders, description, meaning)
147 self.assigned_id = assigned_id
148
149 def ToTclibMessage(self):
150 msg = grit.extern.tclib.Message('utf-8', meaning=self.meaning)
151 self.FillTclibBaseMessage(msg)
152 return msg
153
154 def GetId(self):
155 '''Use the assigned id if we have one.'''
156 if self.assigned_id:
157 return self.assigned_id
158
159 return BaseMessage.GetId(self)
160
161
162 class Translation(BaseMessage):
163 '''A translation.'''
164
165 def __init__(self, text='', id='', placeholders=[], description='', meaning='' ):
166 BaseMessage.__init__(self, text, placeholders, description, meaning)
167 self.id = id
168
169 def GetId(self):
170 assert id != '', "ID has not been set."
171 return self.id
172
173 def SetId(self, id):
174 self.id = id
175
176 def ToTclibMessage(self):
177 msg = grit.extern.tclib.Message(
178 'utf-8', id=self.id, meaning=self.meaning)
179 self.FillTclibBaseMessage(msg)
180 return msg
181
182
183 class Placeholder(grit.extern.tclib.Placeholder):
184 '''Modifies constructor to accept a Unicode string
185 '''
186
187 # Must match placeholder presentation names
188 _NAME_RE = re.compile('^[A-Za-z0-9_]+$')
189
190 def __init__(self, presentation, original, example):
191 '''Creates a new placeholder.
192
193 Args:
194 presentation: 'USERNAME'
195 original: '%s'
196 example: 'Joi'
197 '''
198 assert presentation != ''
199 assert original != ''
200 assert example != ''
201 if not self._NAME_RE.match(presentation):
202 raise exception.InvalidPlaceholderName(presentation)
203 self.presentation = presentation
204 self.original = original
205 self.example = example
206
207 def GetPresentation(self):
208 return self.presentation
209
210 def GetOriginal(self):
211 return self.original
212
213 def GetExample(self):
214 return self.example
215
216
OLDNEW
« no previous file with comments | « grit/shortcuts_unittests.py ('k') | grit/tclib_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698