Package translate :: Package storage :: Module tiki
[hide private]
[frames] | no frames]

Source Code for Module translate.storage.tiki

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  #  
  4  # Copyright 2008 Mozilla Corporation, Zuza Software Foundation 
  5  # 
  6  # This file is part of translate. 
  7  # 
  8  # translate is free software; you can redistribute it and/or modify 
  9  # it under the terms of the GNU General Public License as published by 
 10  # the Free Software Foundation; either version 2 of the License, or 
 11  # (at your option) any later version. 
 12  #  
 13  # translate is distributed in the hope that it will be useful, 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  # GNU General Public License for more details. 
 17  # 
 18  # You should have received a copy of the GNU General Public License 
 19  # along with translate; if not, write to the Free Software 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 21   
 22  """Class that manages TikiWiki files for translation.  Tiki files are <strike>ugly and 
 23  inconsistent</strike> formatted as a single large PHP array with several special  
 24  sections identified by comments.  Example current as of 2008-12-01:: 
 25   
 26    <?php 
 27      // Many comments at the top 
 28      $lang=Array( 
 29      // ### Start of unused words 
 30      "aaa" => "zzz", 
 31      // ### end of unused words 
 32       
 33      // ### start of untranslated words 
 34      // "bbb" => "yyy", 
 35      // ### end of untranslated words 
 36       
 37      // ### start of possibly untranslated words 
 38      "ccc" => "xxx", 
 39      // ### end of possibly untranslated words 
 40       
 41      "ddd" => "www", 
 42      "###end###"=>"###end###"); 
 43    ?> 
 44   
 45  In addition there are several auto-generated //-style comments scattered through the  
 46  page and array, some of which matter when being parsed. 
 47   
 48  This has all been gleaned from the  
 49  U{TikiWiki source<http://tikiwiki.svn.sourceforge.net/viewvc/tikiwiki/trunk/get_strings.php?view=markup>}. 
 50  As far as I know no detailed documentation exists for the tiki language.php files. 
 51   
 52  """ 
 53   
 54  from translate.storage import base 
 55  from translate.misc import wStringIO 
 56  import re 
 57  import datetime 
 58   
59 -class TikiUnit(base.TranslationUnit):
60 """A tiki unit entry."""
61 - def __init__(self, source=None, encoding="UTF-8"):
62 self.location = [] 63 super(TikiUnit, self).__init__(source)
64
65 - def __unicode__(self):
66 """Returns a string formatted to be inserted into a tiki language.php file.""" 67 ret = u'"%s" => "%s",' % (self.source, self.target) 68 if self.location == ["untranslated"]: 69 ret = u'// ' + ret 70 return ret + "\n"
71
72 - def addlocation(self, location):
73 """Location is defined by the comments in the file. This function will only 74 set valid locations. 75 76 @param location: Where the string is located in the file. Must be a valid location. 77 """ 78 if location in ['unused', 'untranslated', 'possiblyuntranslated', 'translated']: 79 self.location.append(location)
80
81 - def getlocations(self):
82 """Returns the a list of the location(s) of the string.""" 83 return self.location
84
85 -class TikiStore(base.TranslationStore):
86 """Represents a tiki language.php file."""
87 - def __init__(self, inputfile=None):
88 """If an inputfile is specified it will be parsed. 89 90 @param inputfile: Either a string or a filehandle of the source file 91 """ 92 base.TranslationStore.__init__(self, TikiUnit) 93 self.units = [] 94 self.filename = getattr(inputfile, 'name', '') 95 if inputfile is not None: 96 self.parse(inputfile)
97
98 - def __str__(self):
99 """Will return a formatted tiki-style language.php file.""" 100 _unused = [] 101 _untranslated = [] 102 _possiblyuntranslated = [] 103 _translated = [] 104 105 output = self._tiki_header() 106 107 # Reorder all the units into their groups 108 for unit in self.units: 109 if unit.getlocations() == ["unused"]: 110 _unused.append(unit) 111 elif unit.getlocations() == ["untranslated"]: 112 _untranslated.append(unit) 113 elif unit.getlocations() == ["possiblyuntranslated"]: 114 _possiblyuntranslated.append(unit) 115 else: 116 _translated.append(unit) 117 118 output += "// ### Start of unused words\n" 119 for unit in _unused: 120 output += unicode(unit) 121 output += "// ### end of unused words\n\n" 122 output += "// ### start of untranslated words\n" 123 for unit in _untranslated: 124 output += unicode(unit) 125 output += "// ### end of untranslated words\n\n" 126 output += "// ### start of possibly untranslated words\n" 127 for unit in _possiblyuntranslated: 128 output += unicode(unit) 129 output += "// ### end of possibly untranslated words\n\n" 130 for unit in _translated: 131 output += unicode(unit) 132 133 output += self._tiki_footer() 134 return output.encode('UTF-8')
135
136 - def _tiki_header(self):
137 """Returns a tiki-file header string.""" 138 return u"<?php // -*- coding:utf-8 -*-\n// Generated from po2tiki on %s\n\n$lang=Array(\n" % datetime.datetime.now()
139 143
144 - def parse(self, input):
145 """Parse the given input into source units. 146 147 @param input: the source, either a string or filehandle 148 """ 149 if hasattr(input, "name"): 150 self.filename = input.name 151 152 if isinstance(input, str): 153 input = wStringIO.StringIO(input) 154 155 _split_regex = re.compile(r"^(?:// )?\"(.*)\" => \"(.*)\",$", re.UNICODE) 156 157 try: 158 _location = "translated" 159 160 for line in input: 161 # The tiki file fails to identify each section so we have to look for start and end 162 # points and if we're outside of them we assume the string is translated 163 if line.count("### Start of unused words"): 164 _location = "unused" 165 elif line.count("### start of untranslated words"): 166 _location = "untranslated" 167 elif line.count("### start of possibly untranslated words"): 168 _location = "possiblyuntranslated" 169 elif line.count("### end of unused words"): 170 _location = "translated" 171 elif line.count("### end of untranslated words"): 172 _location = "translated" 173 elif line.count("### end of possibly untranslated words"): 174 _location = "translated" 175 176 match = _split_regex.match(line) 177 178 if match: 179 unit = self.addsourceunit("".join(match.group(1))) 180 # Untranslated words get an empty msgstr 181 if not _location == "untranslated": 182 unit.settarget(match.group(2)) 183 unit.addlocation(_location) 184 finally: 185 input.close()
186