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  import datetime 
 55  import re 
 56   
 57  from translate.misc import wStringIO 
 58  from translate.storage import base 
 59   
 60   
61 -class TikiUnit(base.TranslationUnit):
62 """A tiki unit entry.""" 63
64 - def __init__(self, source=None, encoding="UTF-8"):
65 self.location = [] 66 super(TikiUnit, self).__init__(source)
67
68 - def __unicode__(self):
69 """Returns a string formatted to be inserted into a tiki language.php file.""" 70 ret = u'"%s" => "%s",' % (self.source, self.target) 71 if self.location == ["untranslated"]: 72 ret = u'// ' + ret 73 return ret + "\n"
74
75 - def addlocation(self, location):
76 """Location is defined by the comments in the file. This function will only 77 set valid locations. 78 79 @param location: Where the string is located in the file. Must be a valid location. 80 """ 81 if location in ['unused', 'untranslated', 'possiblyuntranslated', 'translated']: 82 self.location.append(location)
83
84 - def getlocations(self):
85 """Returns the a list of the location(s) of the string.""" 86 return self.location
87 88
89 -class TikiStore(base.TranslationStore):
90 """Represents a tiki language.php file.""" 91
92 - def __init__(self, inputfile=None):
93 """If an inputfile is specified it will be parsed. 94 95 @param inputfile: Either a string or a filehandle of the source file 96 """ 97 base.TranslationStore.__init__(self, TikiUnit) 98 self.units = [] 99 self.filename = getattr(inputfile, 'name', '') 100 if inputfile is not None: 101 self.parse(inputfile)
102
103 - def __str__(self):
104 """Will return a formatted tiki-style language.php file.""" 105 _unused = [] 106 _untranslated = [] 107 _possiblyuntranslated = [] 108 _translated = [] 109 110 output = self._tiki_header() 111 112 # Reorder all the units into their groups 113 for unit in self.units: 114 if unit.getlocations() == ["unused"]: 115 _unused.append(unit) 116 elif unit.getlocations() == ["untranslated"]: 117 _untranslated.append(unit) 118 elif unit.getlocations() == ["possiblyuntranslated"]: 119 _possiblyuntranslated.append(unit) 120 else: 121 _translated.append(unit) 122 123 output += "// ### Start of unused words\n" 124 for unit in _unused: 125 output += unicode(unit) 126 output += "// ### end of unused words\n\n" 127 output += "// ### start of untranslated words\n" 128 for unit in _untranslated: 129 output += unicode(unit) 130 output += "// ### end of untranslated words\n\n" 131 output += "// ### start of possibly untranslated words\n" 132 for unit in _possiblyuntranslated: 133 output += unicode(unit) 134 output += "// ### end of possibly untranslated words\n\n" 135 for unit in _translated: 136 output += unicode(unit) 137 138 output += self._tiki_footer() 139 return output.encode('UTF-8')
140
141 - def _tiki_header(self):
142 """Returns a tiki-file header string.""" 143 return u"<?php // -*- coding:utf-8 -*-\n// Generated from po2tiki on %s\n\n$lang=Array(\n" % datetime.datetime.now()
144 148
149 - def parse(self, input):
150 """Parse the given input into source units. 151 152 @param input: the source, either a string or filehandle 153 """ 154 if hasattr(input, "name"): 155 self.filename = input.name 156 157 if isinstance(input, str): 158 input = wStringIO.StringIO(input) 159 160 _split_regex = re.compile(r"^(?:// )?\"(.*)\" => \"(.*)\",$", re.UNICODE) 161 162 try: 163 _location = "translated" 164 165 for line in input: 166 # The tiki file fails to identify each section so we have to look for start and end 167 # points and if we're outside of them we assume the string is translated 168 if line.count("### Start of unused words"): 169 _location = "unused" 170 elif line.count("### start of untranslated words"): 171 _location = "untranslated" 172 elif line.count("### start of possibly untranslated words"): 173 _location = "possiblyuntranslated" 174 elif line.count("### end of unused words"): 175 _location = "translated" 176 elif line.count("### end of untranslated words"): 177 _location = "translated" 178 elif line.count("### end of possibly untranslated words"): 179 _location = "translated" 180 181 match = _split_regex.match(line) 182 183 if match: 184 unit = self.addsourceunit("".join(match.group(1))) 185 # Untranslated words get an empty msgstr 186 if not _location == "untranslated": 187 unit.settarget(match.group(2)) 188 unit.addlocation(_location) 189 finally: 190 input.close()
191