| OLD | NEW |
| (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 '''Support for ALL_ALL.xml format used by Igoogle plug-ins in Google Desktop.''' | |
| 7 | |
| 8 import StringIO | |
| 9 import re | |
| 10 import xml.sax | |
| 11 import xml.sax.handler | |
| 12 import xml.sax.saxutils | |
| 13 | |
| 14 from grit.gather import regexp | |
| 15 from grit import util | |
| 16 from grit import tclib | |
| 17 | |
| 18 # Placeholders can be defined in strings.xml files by putting the name of the | |
| 19 # placeholder between [![ and ]!] e.g. <MSG>Hello [![USER]!] how are you<MSG> | |
| 20 PLACEHOLDER_RE = re.compile('(\[!\[|\]!\])') | |
| 21 | |
| 22 | |
| 23 class IgoogleStringsContentHandler(xml.sax.handler.ContentHandler): | |
| 24 '''A very dumb parser for splitting the strings.xml file into translateable | |
| 25 and nontranslateable chunks.''' | |
| 26 | |
| 27 def __init__(self, parent): | |
| 28 self.curr_elem = '' | |
| 29 self.curr_text = '' | |
| 30 self.parent = parent | |
| 31 self.resource_name = '' | |
| 32 self.meaning = '' | |
| 33 self.translateable = True | |
| 34 | |
| 35 def startElement(self, name, attrs): | |
| 36 if (name != 'messagebundle'): | |
| 37 self.curr_elem = name | |
| 38 | |
| 39 attr_names = attrs.getQNames() | |
| 40 if 'name' in attr_names: | |
| 41 self.resource_name = attrs.getValueByQName('name') | |
| 42 | |
| 43 att_text = [] | |
| 44 for attr_name in attr_names: | |
| 45 att_text.append(' ') | |
| 46 att_text.append(attr_name) | |
| 47 att_text.append('=') | |
| 48 att_text.append( | |
| 49 xml.sax.saxutils.quoteattr(attrs.getValueByQName(attr_name))) | |
| 50 | |
| 51 self.parent._AddNontranslateableChunk("<%s%s>" % | |
| 52 (name, ''.join(att_text))) | |
| 53 | |
| 54 def characters(self, content): | |
| 55 if self.curr_elem != '': | |
| 56 self.curr_text += content | |
| 57 | |
| 58 def endElement(self, name): | |
| 59 if name != 'messagebundle': | |
| 60 self.parent.AddMessage(self.curr_text, self.resource_name, | |
| 61 self.meaning, self.translateable) | |
| 62 self.parent._AddNontranslateableChunk("</%s>\n" % name) | |
| 63 self.curr_elem = '' | |
| 64 self.curr_text = '' | |
| 65 self.resource_name = '' | |
| 66 self.meaning = '' | |
| 67 self.translateable = True | |
| 68 | |
| 69 def ignorableWhitespace(self, whitespace): | |
| 70 pass | |
| 71 | |
| 72 | |
| 73 class IgoogleStrings(regexp.RegexpGatherer): | |
| 74 '''Supports the ALL_ALL.xml format used by Igoogle gadgets.''' | |
| 75 | |
| 76 def AddMessage(self, msgtext, description, meaning, translateable): | |
| 77 if msgtext == '': | |
| 78 return | |
| 79 | |
| 80 msg = tclib.Message(description=description, meaning=meaning) | |
| 81 | |
| 82 unescaped_text = self.UnEscape(msgtext) | |
| 83 parts = PLACEHOLDER_RE.split(unescaped_text) | |
| 84 in_placeholder = False | |
| 85 for part in parts: | |
| 86 if part == '': | |
| 87 continue | |
| 88 elif part == '[![': | |
| 89 in_placeholder = True | |
| 90 elif part == ']!]': | |
| 91 in_placeholder = False | |
| 92 else: | |
| 93 if in_placeholder: | |
| 94 msg.AppendPlaceholder(tclib.Placeholder(part, '[![%s]!]' % part, | |
| 95 '(placeholder)')) | |
| 96 else: | |
| 97 msg.AppendText(part) | |
| 98 | |
| 99 self.skeleton_.append( | |
| 100 self.uberclique.MakeClique(msg, translateable=translateable)) | |
| 101 | |
| 102 # if statement needed because this is supposed to be idempotent (so never | |
| 103 # set back to false) | |
| 104 if translateable: | |
| 105 self.translatable_chunk_ = True | |
| 106 | |
| 107 # Although we use the RegexpGatherer base class, we do not use the | |
| 108 # _RegExpParse method of that class to implement Parse(). Instead, we | |
| 109 # parse using a SAX parser. | |
| 110 def Parse(self): | |
| 111 if self.have_parsed_: | |
| 112 return | |
| 113 self.have_parsed_ = True | |
| 114 | |
| 115 self.text_ = self._LoadInputFile().strip() | |
| 116 self._AddNontranslateableChunk(u'<messagebundle>\n') | |
| 117 stream = StringIO.StringIO(self.text_) | |
| 118 handler = IgoogleStringsContentHandler(self) | |
| 119 xml.sax.parse(stream, handler) | |
| 120 self._AddNontranslateableChunk(u'</messagebundle>\n') | |
| 121 | |
| 122 def Escape(self, text): | |
| 123 return util.EncodeCdata(text) | |
| OLD | NEW |