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

Side by Side Diff: grit/gather/skeleton_gatherer.py

Issue 1442863002: Remove contents of grit's SVN repository. (Closed) Base URL: http://grit-i18n.googlecode.com/svn/trunk/
Patch Set: Created 5 years, 1 month 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')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 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 types
11
12 from grit.gather import interface
13 from grit import clique
14 from grit import tclib
15
16
17 class SkeletonGatherer(interface.GathererBase):
18 '''Common functionality of gatherers that parse their input as a skeleton of
19 translatable and nontranslatable chunks.
20 '''
21
22 def __init__(self, *args, **kwargs):
23 super(SkeletonGatherer, self).__init__(*args, **kwargs)
24 # List of parts of the document. Translateable parts are
25 # clique.MessageClique objects, nontranslateable parts are plain strings.
26 # Translated messages are inserted back into the skeleton using the quoting
27 # rules defined by self.Escape()
28 self.skeleton_ = []
29 # A list of the names of IDs that need to be defined for this resource
30 # section to compile correctly.
31 self.ids_ = []
32 # True if Parse() has already been called.
33 self.have_parsed_ = False
34 # True if a translatable chunk has been added
35 self.translatable_chunk_ = False
36 # If not None, all parts of the document will be put into this single
37 # message; otherwise the normal skeleton approach is used.
38 self.single_message_ = None
39 # Number to use for the next placeholder name. Used only if single_message
40 # is not None
41 self.ph_counter_ = 1
42
43 def GetText(self):
44 '''Returns the original text of the section'''
45 return self.text_
46
47 def Escape(self, text):
48 '''Subclasses can override. Base impl is identity.
49 '''
50 return text
51
52 def UnEscape(self, text):
53 '''Subclasses can override. Base impl is identity.
54 '''
55 return text
56
57 def GetTextualIds(self):
58 '''Returns the list of textual IDs that need to be defined for this
59 resource section to compile correctly.'''
60 return self.ids_
61
62 def _AddTextualId(self, id):
63 self.ids_.append(id)
64
65 def GetCliques(self):
66 '''Returns the message cliques for each translateable message in the
67 resource section.'''
68 return [x for x in self.skeleton_ if isinstance(x, clique.MessageClique)]
69
70 def Translate(self, lang, pseudo_if_not_available=True,
71 skeleton_gatherer=None, fallback_to_english=False):
72 if len(self.skeleton_) == 0:
73 raise exception.NotReady()
74 if skeleton_gatherer:
75 assert len(skeleton_gatherer.skeleton_) == len(self.skeleton_)
76
77 out = []
78 for ix in range(len(self.skeleton_)):
79 if isinstance(self.skeleton_[ix], types.StringTypes):
80 if skeleton_gatherer:
81 # Make sure the skeleton is like the original
82 assert(isinstance(skeleton_gatherer.skeleton_[ix], types.StringTypes))
83 out.append(skeleton_gatherer.skeleton_[ix])
84 else:
85 out.append(self.skeleton_[ix])
86 else:
87 if skeleton_gatherer: # Make sure the skeleton is like the original
88 assert(not isinstance(skeleton_gatherer.skeleton_[ix],
89 types.StringTypes))
90 msg = self.skeleton_[ix].MessageForLanguage(lang,
91 pseudo_if_not_available,
92 fallback_to_english)
93
94 def MyEscape(text):
95 return self.Escape(text)
96 text = msg.GetRealContent(escaping_function=MyEscape)
97 out.append(text)
98 return ''.join(out)
99
100 def Parse(self):
101 '''Parses the section. Implemented by subclasses. Idempotent.'''
102 raise NotImplementedError()
103
104 def _AddNontranslateableChunk(self, chunk):
105 '''Adds a nontranslateable chunk.'''
106 if self.single_message_:
107 ph = tclib.Placeholder('XX%02dXX' % self.ph_counter_, chunk, chunk)
108 self.ph_counter_ += 1
109 self.single_message_.AppendPlaceholder(ph)
110 else:
111 self.skeleton_.append(chunk)
112
113 def _AddTranslateableChunk(self, chunk):
114 '''Adds a translateable chunk. It will be unescaped before being added.'''
115 # We don't want empty messages since they are redundant and the TC
116 # doesn't allow them.
117 if chunk == '':
118 return
119
120 unescaped_text = self.UnEscape(chunk)
121 if self.single_message_:
122 self.single_message_.AppendText(unescaped_text)
123 else:
124 self.skeleton_.append(self.uberclique.MakeClique(
125 tclib.Message(text=unescaped_text)))
126 self.translatable_chunk_ = True
127
128 def SubstituteMessages(self, substituter):
129 '''Applies substitutions to all messages in the tree.
130
131 Goes through the skeleton and finds all MessageCliques.
132
133 Args:
134 substituter: a grit.util.Substituter object.
135 '''
136 if self.single_message_:
137 self.single_message_ = substituter.SubstituteMessage(self.single_message_)
138 new_skel = []
139 for chunk in self.skeleton_:
140 if isinstance(chunk, clique.MessageClique):
141 old_message = chunk.GetMessage()
142 new_message = substituter.SubstituteMessage(old_message)
143 if new_message is not old_message:
144 new_skel.append(self.uberclique.MakeClique(new_message))
145 continue
146 new_skel.append(chunk)
147 self.skeleton_ = new_skel
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