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

Side by Side Diff: grit/xtb_reader.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/util_unittest.py ('k') | grit/xtb_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')
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 '''Fast and efficient parser for XTB files.
7 '''
8
9
10 import sys
11 import xml.sax
12 import xml.sax.handler
13
14 import grit.node.base
15
16
17 class XtbContentHandler(xml.sax.handler.ContentHandler):
18 '''A content handler that calls a given callback function for each
19 translation in the XTB file.
20 '''
21
22 def __init__(self, callback, defs=None, debug=False, target_platform=None):
23 self.callback = callback
24 self.debug = debug
25 # 0 if we are not currently parsing a translation, otherwise the message
26 # ID of that translation.
27 self.current_id = 0
28 # Empty if we are not currently parsing a translation, otherwise the
29 # parts we have for that translation - a list of tuples
30 # (is_placeholder, text)
31 self.current_structure = []
32 # Set to the language ID when we see the <translationbundle> node.
33 self.language = ''
34 # Keep track of the if block we're inside. We can't nest ifs.
35 self.if_expr = None
36 # Root defines to be used with if expr.
37 if defs:
38 self.defines = defs
39 else:
40 self.defines = {}
41 # Target platform for build.
42 if target_platform:
43 self.target_platform = target_platform
44 else:
45 self.target_platform = sys.platform
46
47 def startElement(self, name, attrs):
48 if name == 'translation':
49 assert self.current_id == 0 and len(self.current_structure) == 0, (
50 "Didn't expect a <translation> element here.")
51 self.current_id = attrs.getValue('id')
52 elif name == 'ph':
53 assert self.current_id != 0, "Didn't expect a <ph> element here."
54 self.current_structure.append((True, attrs.getValue('name')))
55 elif name == 'translationbundle':
56 self.language = attrs.getValue('lang')
57 elif name in ('if', 'then', 'else'):
58 assert self.if_expr is None, "Can't nest <if> or use <else> in xtb files"
59 self.if_expr = attrs.getValue('expr')
60
61 def endElement(self, name):
62 if name == 'translation':
63 assert self.current_id != 0
64
65 defs = self.defines
66 def pp_ifdef(define):
67 return define in defs
68 def pp_if(define):
69 return define in defs and defs[define]
70
71 # If we're in an if block, only call the callback (add the translation)
72 # if the expression is True.
73 should_run_callback = True
74 if self.if_expr:
75 should_run_callback = grit.node.base.Node.EvaluateExpression(
76 self.if_expr, self.defines, self.target_platform)
77 if should_run_callback:
78 self.callback(self.current_id, self.current_structure)
79
80 self.current_id = 0
81 self.current_structure = []
82 elif name == 'if':
83 assert self.if_expr is not None
84 self.if_expr = None
85
86 def characters(self, content):
87 if self.current_id != 0:
88 # We are inside a <translation> node so just add the characters to our
89 # structure.
90 #
91 # This naive way of handling characters is OK because in the XTB format,
92 # <ph> nodes are always empty (always <ph name="XXX"/>) and whitespace
93 # inside the <translation> node should be preserved.
94 self.current_structure.append((False, content))
95
96
97 class XtbErrorHandler(xml.sax.handler.ErrorHandler):
98 def error(self, exception):
99 pass
100
101 def fatalError(self, exception):
102 raise exception
103
104 def warning(self, exception):
105 pass
106
107
108 def Parse(xtb_file, callback_function, defs=None, debug=False,
109 target_platform=None):
110 '''Parse xtb_file, making a call to callback_function for every translation
111 in the XTB file.
112
113 The callback function must have the signature as described below. The 'parts'
114 parameter is a list of tuples (is_placeholder, text). The 'text' part is
115 either the raw text (if is_placeholder is False) or the name of the placeholde r
116 (if is_placeholder is True).
117
118 Args:
119 xtb_file: open('fr.xtb')
120 callback_function: def Callback(msg_id, parts): pass
121 defs: None, or a dictionary of preprocessor definitions.
122 debug: Default False. Set True for verbose debug output.
123 target_platform: None, or a sys.platform-like identifier of the build
124 target platform.
125
126 Return:
127 The language of the XTB, e.g. 'fr'
128 '''
129 # Start by advancing the file pointer past the DOCTYPE thing, as the TC
130 # uses a path to the DTD that only works in Unix.
131 # TODO(joi) Remove this ugly hack by getting the TC gang to change the
132 # XTB files somehow?
133 front_of_file = xtb_file.read(1024)
134 xtb_file.seek(front_of_file.find('<translationbundle'))
135
136 handler = XtbContentHandler(callback=callback_function, defs=defs,
137 debug=debug, target_platform=target_platform)
138 xml.sax.parse(xtb_file, handler)
139 assert handler.language != ''
140 return handler.language
141
OLDNEW
« no previous file with comments | « grit/util_unittest.py ('k') | grit/xtb_reader_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698