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

Side by Side Diff: grit/gather/skeleton_gatherer.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/gather/regexp.py ('k') | grit/gather/tr_html.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) 2011 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 '''A baseclass for simple gatherers that store their gathered resource in a
7 list.
8 '''
9
10 import re
11 import types
12
13 from grit.gather import interface
14 from grit import clique
15 from grit import tclib
16
17
18 class SkeletonGatherer(interface.GathererBase):
19 '''Common functionality of gatherers that parse their input as a skeleton of
20 translatable and nontranslatable chunks.
21 '''
22
23 def __init__(self):
24 interface.GathererBase.__init__(self)
25 # List of parts of the document. Translateable parts are
26 # clique.MessageClique objects, nontranslateable parts are plain strings.
27 # Translated messages are inserted back into the skeleton using the quoting
28 # rules defined by self.Escape()
29 self.skeleton_ = []
30 # A list of the names of IDs that need to be defined for this resource
31 # section to compile correctly.
32 self.ids_ = []
33 # True if Parse() has already been called.
34 self.have_parsed_ = False
35 # True if a translatable chunk has been added
36 self.translatable_chunk_ = False
37 # If not None, all parts of the document will be put into this single
38 # message; otherwise the normal skeleton approach is used.
39 self.single_message_ = None
40 # Number to use for the next placeholder name. Used only if single_message
41 # is not None
42 self.ph_counter_ = 1
43
44 def GetText(self):
45 '''Returns the original text of the section'''
46 return self.text_
47
48 def Escape(self, text):
49 '''Subclasses can override. Base impl is identity.
50 '''
51 return text
52
53 def UnEscape(self, text):
54 '''Subclasses can override. Base impl is identity.
55 '''
56 return text
57
58 def GetTextualIds(self):
59 '''Returns the list of textual IDs that need to be defined for this
60 resource section to compile correctly.'''
61 return self.ids_
62
63 def _AddTextualId(self, id):
64 self.ids_.append(id)
65
66 def GetCliques(self):
67 '''Returns the message cliques for each translateable message in the
68 resource section.'''
69 return filter(lambda x: isinstance(x, clique.MessageClique), self.skeleton_)
70
71 def Translate(self, lang, pseudo_if_not_available=True,
72 skeleton_gatherer=None, fallback_to_english=False):
73 if len(self.skeleton_) == 0:
74 raise exception.NotReady()
75 if skeleton_gatherer:
76 assert len(skeleton_gatherer.skeleton_) == len(self.skeleton_)
77
78 out = []
79 for ix in range(len(self.skeleton_)):
80 if isinstance(self.skeleton_[ix], types.StringTypes):
81 if skeleton_gatherer:
82 # Make sure the skeleton is like the original
83 assert(isinstance(skeleton_gatherer.skeleton_[ix], types.StringTypes))
84 out.append(skeleton_gatherer.skeleton_[ix])
85 else:
86 out.append(self.skeleton_[ix])
87 else:
88 if skeleton_gatherer: # Make sure the skeleton is like the original
89 assert(not isinstance(skeleton_gatherer.skeleton_[ix],
90 types.StringTypes))
91 msg = self.skeleton_[ix].MessageForLanguage(lang,
92 pseudo_if_not_available,
93 fallback_to_english)
94
95 def MyEscape(text):
96 return self.Escape(text)
97 text = msg.GetRealContent(escaping_function=MyEscape)
98 out.append(text)
99 return ''.join(out)
100
101 def Parse(self):
102 '''Parses the section. Implemented by subclasses. Idempotent.'''
103 raise NotImplementedError()
104
105 def _AddNontranslateableChunk(self, chunk):
106 '''Adds a nontranslateable chunk.'''
107 if self.single_message_:
108 ph = tclib.Placeholder('XX%02dXX' % self.ph_counter_, chunk, chunk)
109 self.ph_counter_ += 1
110 self.single_message_.AppendPlaceholder(ph)
111 else:
112 self.skeleton_.append(chunk)
113
114 def _AddTranslateableChunk(self, chunk):
115 '''Adds a translateable chunk. It will be unescaped before being added.'''
116 # We don't want empty messages since they are redundant and the TC
117 # doesn't allow them.
118 if chunk == '':
119 return
120
121 unescaped_text = self.UnEscape(chunk)
122 if self.single_message_:
123 self.single_message_.AppendText(unescaped_text)
124 else:
125 self.skeleton_.append(self.uberclique.MakeClique(
126 tclib.Message(text=unescaped_text)))
127 self.translatable_chunk_ = True
OLDNEW
« no previous file with comments | « grit/gather/regexp.py ('k') | grit/gather/tr_html.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698