Index: grit/node/structure.py |
=================================================================== |
--- grit/node/structure.py (revision 0) |
+++ grit/node/structure.py (revision 0) |
@@ -0,0 +1,263 @@ |
+#!/usr/bin/python2.4 |
+# Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+'''The <structure> element. |
+''' |
+ |
+import os |
+ |
+from grit.node import base |
+from grit.node import variant |
+ |
+from grit import constants |
+from grit import exception |
+from grit import util |
+ |
+import grit.gather.rc |
+import grit.gather.tr_html |
+import grit.gather.admin_template |
+import grit.gather.txt |
+import grit.gather.muppet_strings |
+import grit.gather.policy_json |
+ |
+import grit.format.rc |
+import grit.format.rc_header |
+ |
+# RTL languages |
+# TODO(jennyz): remove this fixed set of RTL language array |
+# when generic expand_variable code is added by grit team. |
+_RTL_LANGS = [ |
+ 'ar', |
+ 'iw', |
+ 'ur', |
+] |
+ |
+# Type of the gatherer to use for each type attribute |
+_GATHERERS = { |
+ 'accelerators' : grit.gather.rc.Accelerators, |
+ 'admin_template' : grit.gather.admin_template.AdmGatherer, |
+ 'dialog' : grit.gather.rc.Dialog, |
+ 'menu' : grit.gather.rc.Menu, |
+ 'muppet' : grit.gather.muppet_strings.MuppetStrings, |
+ 'rcdata' : grit.gather.rc.RCData, |
+ 'tr_html' : grit.gather.tr_html.TrHtml, |
+ 'txt' : grit.gather.txt.TxtFile, |
+ 'version' : grit.gather.rc.Version, |
+ 'policy_template_metafile' : grit.gather.policy_json.PolicyJson, |
+} |
+ |
+ |
+# Formatter instance to use for each type attribute |
+# when formatting .rc files. |
+_RC_FORMATTERS = { |
+ 'accelerators' : grit.format.rc.RcSection(), |
+ 'admin_template' : grit.format.rc.RcInclude('ADM'), |
+ 'dialog' : grit.format.rc.RcSection(), |
+ 'menu' : grit.format.rc.RcSection(), |
+ 'muppet' : grit.format.rc.RcInclude('XML'), |
+ 'rcdata' : grit.format.rc.RcSection(), |
+ 'tr_html' : grit.format.rc.RcInclude('HTML'), |
+ 'txt' : grit.format.rc.RcInclude('TXT'), |
+ 'version' : grit.format.rc.RcSection(), |
+ 'policy_template_metafile': None, |
+} |
+ |
+ |
+# TODO(joi) Print a warning if the 'variant_of_revision' attribute indicates |
+# that a skeleton variant is older than the original file. |
+ |
+ |
+class StructureNode(base.Node): |
+ '''A <structure> element.''' |
+ |
+ def __init__(self): |
+ base.Node.__init__(self) |
+ self.gatherer = None |
+ self.skeletons = {} # expressions to skeleton gatherers |
+ |
+ def _IsValidChild(self, child): |
+ return isinstance(child, variant.SkeletonNode) |
+ |
+ def MandatoryAttributes(self): |
+ return ['type', 'name', 'file'] |
+ |
+ def DefaultAttributes(self): |
+ return { 'encoding' : 'cp1252', |
+ 'exclude_from_rc' : 'false', |
+ 'line_end' : 'unix', |
+ 'output_encoding' : 'utf-8', |
+ 'generateid': 'true', |
+ 'expand_variables' : 'false', |
+ 'output_filename' : '', |
+ # TODO(joi) this is a hack - should output all generated files |
+ # as SCons dependencies; however, for now there is a bug I can't |
+ # find where GRIT doesn't build the matching fileset, therefore |
+ # this hack so that only the files you really need are marked as |
+ # dependencies. |
+ 'sconsdep' : 'false', |
+ } |
+ |
+ def IsExcludedFromRc(self): |
+ return self.attrs['exclude_from_rc'] == 'true' |
+ |
+ def GetLineEnd(self): |
+ '''Returns the end-of-line character or characters for files output because |
+ of this node ('\r\n', '\n', or '\r' depending on the 'line_end' attribute). |
+ ''' |
+ if self.attrs['line_end'] == 'unix': |
+ return '\n' |
+ elif self.attrs['line_end'] == 'windows': |
+ return '\r\n' |
+ elif self.attrs['line_end'] == 'mac': |
+ return '\r' |
+ else: |
+ raise exception.UnexpectedAttribute( |
+ "Attribute 'line_end' must be one of 'linux' (default), 'windows' or 'mac'") |
+ |
+ def GetCliques(self): |
+ if self.gatherer: |
+ return self.gatherer.GetCliques() |
+ else: |
+ return [] |
+ |
+ def GetTextualIds(self): |
+ if self.gatherer and self.attrs['type'] not in ['tr_html', 'admin_template', 'txt']: |
+ return self.gatherer.GetTextualIds() |
+ else: |
+ return [self.attrs['name']] |
+ |
+ def ItemFormatter(self, t): |
+ if t == 'rc_header': |
+ return grit.format.rc_header.Item() |
+ elif (t in ['rc_all', 'rc_translateable', 'rc_nontranslateable'] and |
+ self.SatisfiesOutputCondition()): |
+ return _RC_FORMATTERS[self.attrs['type']] |
+ else: |
+ return super(type(self), self).ItemFormatter(t) |
+ |
+ def RunGatherers(self, recursive=False, debug=False): |
+ if self.gatherer: |
+ return # idempotent |
+ |
+ gathertype = _GATHERERS[self.attrs['type']] |
+ |
+ if debug: |
+ print 'Running gatherer %s for file %s' % (str(gathertype), self.FilenameToOpen()) |
+ |
+ self.gatherer = gathertype.FromFile(self.FilenameToOpen(), |
+ self.attrs['name'], |
+ self.attrs['encoding']) |
+ self.gatherer.SetUberClique(self.UberClique()) |
+ self.gatherer.Parse() |
+ |
+ for child in self.children: |
+ assert isinstance(child, variant.SkeletonNode) |
+ skel = gathertype.FromFile(child.FilenameToOpen(), |
+ self.attrs['name'], |
+ child.GetEncodingToUse()) |
+ skel.SetUberClique(self.UberClique()) |
+ skel.SetSkeleton(True) |
+ skel.Parse() |
+ self.skeletons[child.attrs['expr']] = skel |
+ |
+ def GetSkeletonGatherer(self): |
+ '''Returns the gatherer for the alternate skeleton that should be used, |
+ based on the expressions for selecting skeletons, or None if the skeleton |
+ from the English version of the structure should be used. |
+ ''' |
+ for expr in self.skeletons: |
+ if self.EvaluateCondition(expr): |
+ return self.skeletons[expr] |
+ return None |
+ |
+ def GetFilePath(self): |
+ return self.ToRealPath(self.attrs['file']) |
+ |
+ def HasFileForLanguage(self): |
+ return self.attrs['type'] in ['tr_html', 'admin_template', 'txt', 'muppet'] |
+ |
+ def FileForLanguage(self, lang, output_dir, create_file=True, |
+ return_if_not_generated=True): |
+ '''Returns the filename of the file associated with this structure, |
+ for the specified language. |
+ |
+ Args: |
+ lang: 'fr' |
+ output_dir: 'c:\temp' |
+ create_file: True |
+ ''' |
+ assert self.HasFileForLanguage() |
+ if (lang == self.GetRoot().GetSourceLanguage() and |
+ self.attrs['expand_variables'] != 'true'): |
+ if return_if_not_generated: |
+ return self.GetFilePath() |
+ else: |
+ return None |
+ else: |
+ if self.attrs['output_filename'] != '': |
+ filename = self.attrs['output_filename'] |
+ else: |
+ filename = os.path.basename(self.attrs['file']) |
+ assert len(filename) |
+ filename = '%s_%s' % (lang, filename) |
+ filename = os.path.join(output_dir, filename) |
+ |
+ if create_file: |
+ text = self.gatherer.Translate( |
+ lang, |
+ pseudo_if_not_available=self.PseudoIsAllowed(), |
+ fallback_to_english=self.ShouldFallbackToEnglish(), |
+ skeleton_gatherer=self.GetSkeletonGatherer()) |
+ |
+ file_object = util.WrapOutputStream(file(filename, 'wb'), |
+ self._GetOutputEncoding()) |
+ file_contents = util.FixLineEnd(text, self.GetLineEnd()) |
+ if self.attrs['expand_variables'] == 'true': |
+ file_contents = file_contents.replace('[GRITLANGCODE]', lang) |
+ # TODO(jennyz): remove this hard coded logic for expanding |
+ # [GRITDIR] variable for RTL languages when the generic |
+ # expand_variable code is added by grit team. |
+ if lang in _RTL_LANGS : |
+ file_contents = file_contents.replace('[GRITDIR]', 'dir="RTL"') |
+ else : |
+ file_contents = file_contents.replace('[GRITDIR]', 'dir="LTR"') |
+ if self._ShouldAddBom(): |
+ file_object.write(constants.BOM) |
+ file_object.write(file_contents) |
+ file_object.close() |
+ |
+ return filename |
+ |
+ def _GetOutputEncoding(self): |
+ '''Python doesn't natively support UTF encodings with a BOM signature, |
+ so we add support by allowing you to append '-sig' to the encoding name. |
+ This function returns the specified output encoding minus that part. |
+ ''' |
+ enc = self.attrs['output_encoding'] |
+ if enc.endswith('-sig'): |
+ return enc[0:len(enc) - len('-sig')] |
+ else: |
+ return enc |
+ |
+ def _ShouldAddBom(self): |
+ '''Returns true if output files should have the Unicode BOM prepended. |
+ ''' |
+ return self.attrs['output_encoding'].endswith('-sig') |
+ |
+ # static method |
+ def Construct(parent, name, type, file, encoding='cp1252'): |
+ '''Creates a new node which is a child of 'parent', with attributes set |
+ by parameters of the same name. |
+ ''' |
+ node = StructureNode() |
+ node.StartParsing('structure', parent) |
+ node.HandleAttribute('name', name) |
+ node.HandleAttribute('type', type) |
+ node.HandleAttribute('file', file) |
+ node.HandleAttribute('encoding', encoding) |
+ node.EndParsing() |
+ return node |
+ Construct = staticmethod(Construct) |
+ |
Property changes on: grit/node/structure.py |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |