1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
60 """A tiki unit entry."""
61 - def __init__(self, source=None, encoding="UTF-8"):
64
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
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
82 """Returns the a list of the location(s) of the string."""
83 return self.location
84
86 """Represents a tiki language.php file."""
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
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
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
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
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
162
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
181 if not _location == "untranslated":
182 unit.settarget(match.group(2))
183 unit.addlocation(_location)
184 finally:
185 input.close()
186