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

Side by Side Diff: grit/grd_reader.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/txt_unittest.py ('k') | grit/grd_reader_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) 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 '''Class for reading GRD files into memory, without processing them.
7 '''
8
9 import os.path
10 import types
11 import xml.sax
12 import xml.sax.handler
13
14 from grit import exception
15 from grit.node import base
16 from grit.node import mapping
17 from grit.node import misc
18 from grit import util
19
20
21 class StopParsingException(Exception):
22 '''An exception used to stop parsing.'''
23 pass
24
25
26 class GrdContentHandler(xml.sax.handler.ContentHandler):
27 def __init__(self,
28 stop_after=None, debug=False, defines=None, tags_to_ignore=None):
29 # Invariant of data:
30 # 'root' is the root of the parse tree being created, or None if we haven't
31 # parsed out any elements.
32 # 'stack' is the a stack of elements that we push new nodes onto and
33 # pop from when they finish parsing, or [] if we are not currently parsing.
34 # 'stack[-1]' is the top of the stack.
35 self.root = None
36 self.stack = []
37 self.stop_after = stop_after
38 self.debug = debug
39 self.defines = defines
40 self.tags_to_ignore = tags_to_ignore or set()
41 self.ignore_depth = 0
42
43 def startElement(self, name, attrs):
44 assert not self.root or len(self.stack) > 0
45
46 if name in self.tags_to_ignore:
47 self.ignore_depth += 1
48 if self.debug:
49 print "Ignoring element %s and its children" % name
50
51 if self.ignore_depth != 0:
52 return
53
54 if self.debug:
55 attr_list = []
56 for attr in attrs.getNames():
57 attr_list.append('%s="%s"' % (attr, attrs.getValue(attr)))
58 if len(attr_list) == 0: attr_list = ['(none)']
59 attr_list = ' '.join(attr_list)
60 print ("Starting parsing of element %s with attributes %r" %
61 (name, attr_list))
62
63 typeattr = None
64 if 'type' in attrs.getNames():
65 typeattr = attrs.getValue('type')
66
67 node = mapping.ElementToClass(name, typeattr)()
68
69 if not self.root:
70 self.root = node
71 if self.defines:
72 self.root.SetDefines(self.defines)
73
74 if len(self.stack) > 0:
75 self.stack[-1].AddChild(node)
76 node.StartParsing(name, self.stack[-1])
77 else:
78 node.StartParsing(name, None)
79
80 # Push
81 self.stack.append(node)
82
83 for attr in attrs.getNames():
84 node.HandleAttribute(attr, attrs.getValue(attr))
85
86 def endElement(self, name):
87 if self.ignore_depth == 0:
88 if self.debug:
89 print "End parsing of element %s" % name
90 # Pop
91 self.stack[-1].EndParsing()
92 assert len(self.stack) > 0
93 self.stack = self.stack[:-1]
94 if self.stop_after and name == self.stop_after:
95 raise StopParsingException()
96
97 if name in self.tags_to_ignore:
98 self.ignore_depth -= 1
99
100 def characters(self, content):
101 if self.ignore_depth == 0:
102 if self.stack[-1]:
103 self.stack[-1].AppendContent(content)
104
105 def ignorableWhitespace(self, whitespace):
106 # TODO(joi) This is not supported by expat. Should use a different XML par ser?
107 pass
108
109
110 def Parse(filename_or_stream, dir=None, flexible_root=False,
111 stop_after=None, debug=False, first_id_filename=None,
112 defines=None, tags_to_ignore=None):
113 '''Parses a GRD file into a tree of nodes (from grit.node).
114
115 If flexible_root is False, the root node must be a <grit> element. Otherwise
116 it can be any element. The "own" directory of the file will only be fixed up
117 if the root node is a <grit> element.
118
119 'dir' should point to the directory of the input file, or be the full path
120 to the input file (the filename will be stripped).
121
122 If 'stop_after' is provided, the parsing will stop once the first node
123 with this name has been fully parsed (including all its contents).
124
125 If 'debug' is true, lots of information about the parsing events will be
126 printed out during parsing of the file.
127
128 If first_id_filename is provided, then we use the provided path instead of
129 resources_id to gather the first id values for resources.
130
131 Args:
132 filename_or_stream: './bla.xml' (must be filename if dir is None)
133 dir: '.' or None (only if filename_or_stream is a filename)
134 flexible_root: True | False
135 stop_after: 'inputs'
136 debug: False
137 first_id_filename: None
138 defines: dictionary of defines, like {'chromeos': '1'}
139
140 Return:
141 Subclass of grit.node.base.Node
142
143 Throws:
144 grit.exception.Parsing
145 '''
146 handler = GrdContentHandler(stop_after=stop_after, debug=debug,
147 defines=defines, tags_to_ignore=tags_to_ignore)
148 try:
149 xml.sax.parse(filename_or_stream, handler)
150 except StopParsingException:
151 assert stop_after
152 pass
153 except:
154 if not debug:
155 print "parse exception: run GRIT with the -x flag to debug .grd problems"
156 raise
157
158 if not flexible_root or hasattr(handler.root, 'SetOwnDir'):
159 assert isinstance(filename_or_stream, types.StringType) or dir != None
160 if not dir:
161 dir = util.dirname(filename_or_stream)
162 if len(dir) == 0:
163 dir = '.'
164 # Fix up the base_dir so it is relative to the input file.
165 handler.root.SetOwnDir(dir)
166
167 # Assign first ids to the nodes that don't have them.
168 if isinstance(handler.root, misc.GritNode) and first_id_filename != '':
169 handler.root.AssignFirstIds(filename_or_stream, first_id_filename, defines)
170
171 return handler.root
172
173
174 if __name__ == '__main__':
175 util.ChangeStdoutEncoding()
176 print unicode(Parse(sys.argv[1]))
OLDNEW
« no previous file with comments | « grit/gather/txt_unittest.py ('k') | grit/grd_reader_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698