Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/translate-toolkit-1.5.1/translate/convert
diff options
context:
space:
mode:
Diffstat (limited to 'translate-toolkit-1.5.1/translate/convert')
-rw-r--r--translate-toolkit-1.5.1/translate/convert/TODO42
-rw-r--r--translate-toolkit-1.5.1/translate/convert/__init__.py31
-rw-r--r--translate-toolkit-1.5.1/translate/convert/accesskey.py109
-rw-r--r--translate-toolkit-1.5.1/translate/convert/convert.py371
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/csv2po27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/csv2po.py200
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/csv2tbx27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/csv2tbx.py77
-rw-r--r--translate-toolkit-1.5.1/translate/convert/dtd2po.py313
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/html2po29
-rw-r--r--translate-toolkit-1.5.1/translate/convert/html2po.py76
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/ical2po27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/ical2po.py105
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/ini2po27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/ini2po.py112
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/moz2po27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/moz2po.py57
-rw-r--r--translate-toolkit-1.5.1/translate/convert/mozfunny2prop.py122
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/odf2xliff35
-rw-r--r--translate-toolkit-1.5.1/translate/convert/odf2xliff.py129
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/oo2po28
-rw-r--r--translate-toolkit-1.5.1/translate/convert/oo2po.py156
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/oo2xliff27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/oo2xliff.py154
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/php2po29
-rw-r--r--translate-toolkit-1.5.1/translate/convert/php2po.py107
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2csv27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2csv.py90
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2dtd.py174
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2html29
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2html.py124
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2ical27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2ical.py75
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2ini27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2ini.py78
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2moz28
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2moz.py111
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2oo31
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2oo.py229
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2php29
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2php.py133
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2prop27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2prop.py139
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2rc28
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2rc.py108
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2sub27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2sub.py75
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2symb27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2symb.py104
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2tiki26
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2tiki.py79
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2tmx29
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2tmx.py114
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2ts29
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2ts.py86
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2txt29
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2txt.py104
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2web2py27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2web2py.py70
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2wordfast28
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2wordfast.py101
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/po2xliff29
-rw-r--r--translate-toolkit-1.5.1/translate/convert/po2xliff.py111
-rw-r--r--translate-toolkit-1.5.1/translate/convert/poreplace.py61
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/pot2po27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/pot2po.py253
-rw-r--r--translate-toolkit-1.5.1/translate/convert/prop2mozfunny.py140
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/prop2po27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/prop2po.py167
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/rc2po27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/rc2po.py119
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/sub2po27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/sub2po.py102
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/symb2po27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/symb2po.py110
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_accesskey.py66
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_convert.py132
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_csv2po.py130
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_dtd2po.py365
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_html2po.py430
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_moz2po.py19
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_mozfunny2prop.py53
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_oo2po.py228
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_oo2xliff.py70
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_php2po.py142
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2csv.py144
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2dtd.py285
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2html.py94
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2moz.py21
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2oo.py182
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2php.py119
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2prop.py112
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2tiki.py40
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2tmx.py154
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2ts.py91
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2txt.py60
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_po2xliff.py296
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_pot2po.py609
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_prop2mozfunny.py39
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_prop2po.py210
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_tiki2po.py56
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_ts2po.py118
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_txt2po.py136
-rw-r--r--translate-toolkit-1.5.1/translate/convert/test_xliff2po.py220
-rw-r--r--translate-toolkit-1.5.1/translate/convert/tiki2po27
-rw-r--r--translate-toolkit-1.5.1/translate/convert/tiki2po.py90
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/ts2po29
-rw-r--r--translate-toolkit-1.5.1/translate/convert/ts2po.py87
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/txt2po29
-rw-r--r--translate-toolkit-1.5.1/translate/convert/txt2po.py75
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/web2py2po26
-rw-r--r--translate-toolkit-1.5.1/translate/convert/web2py2po.py80
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/xliff2odf37
-rw-r--r--translate-toolkit-1.5.1/translate/convert/xliff2odf.py128
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/xliff2oo31
-rw-r--r--translate-toolkit-1.5.1/translate/convert/xliff2oo.py226
-rwxr-xr-xtranslate-toolkit-1.5.1/translate/convert/xliff2po29
-rw-r--r--translate-toolkit-1.5.1/translate/convert/xliff2po.py94
118 files changed, 11749 insertions, 0 deletions
diff --git a/translate-toolkit-1.5.1/translate/convert/TODO b/translate-toolkit-1.5.1/translate/convert/TODO
new file mode 100644
index 0000000..872582d
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/TODO
@@ -0,0 +1,42 @@
+--update option
+ make recursive methods only run if input is newer than output
+--force option
+ only overwrite files if this is given (work out which tools its applicable to)
+
+detect whether producing a .po or a .pot (make -P / --pot unneccessary)
+
+moz2po
+ make strings fuzzy if original == translation
+
+headers
+ charset=UTF-8
+
+copyright
+ need to insert the standard copyright text unitialised
+
+csv2po
+ * change order of columns: original, translation, other stuff
+ * It does not currently reflow text to create a newline around literal \n
+ making it difficult to check files
+ * allow a --no-wrap option so that we remove PO line breaks that mess with
+ translators segmentation tools.
+ * We do not handle languages with N != 2 plural forms
+
+oo2po / po2oo
+ fix problem with OOO_VENDOR and \" quoting in offmgr.po (see help - about)
+ make oo output order the same as in input file...
+
+pot2po discussion with pavel:
+ pot2po should be as simple as using pot as one arg and po as the second ;-)
+ pot2po pot po -t po warns me for every file: pot2po: warning: writing to temporary output...
+ pot2po pot po -t po does not merge existing translations from old POs that have more then one comment and thus are duplicated in the new POs
+
+docs
+ not sure where else to put this!
+ docs are installed in /usr/lib/python2.3/site-packages/translate/doc
+ should be /usr/share/docs/translate-toolkit-0.8
+ Not sure what's needed on Windows - non critical
+
+po2dtd
+ when reporting ampersand check failures should tell you the file not just the
+ name of the bad PO file not just the command line output name
diff --git a/translate-toolkit-1.5.1/translate/convert/__init__.py b/translate-toolkit-1.5.1/translate/convert/__init__.py
new file mode 100644
index 0000000..a1e2e07
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/__init__.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2005 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""translate.convert is part of the translate package
+It contains code to convert between different storage formats for localizations
+
+@group XLIFF: *xliff*
+@group Bilingual: pot2po po2tmx oo2po po2oo csv2tbx *wordfast* *ts*
+@group Monolingual: *prop* *dtd* csv2po po2csv *html* *ical* *ini* *rc* *txt* moz2po po2moz *php* *sub* *symb* *monopo* *tiki* *web2py* *lang*
+@group Support: accesskey convert
+@group Other: poreplace
+"""
+
diff --git a/translate-toolkit-1.5.1/translate/convert/accesskey.py b/translate-toolkit-1.5.1/translate/convert/accesskey.py
new file mode 100644
index 0000000..5c076ab
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/accesskey.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2008 Zuza Software Foundation
+#
+# This file is part of The Translate Toolkit.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""functions used to manipulate access keys in strings"""
+
+from translate.storage.placeables.general import XMLEntityPlaceable
+
+DEFAULT_ACCESSKEY_MARKER = u"&"
+
+def extract(string, accesskey_marker=DEFAULT_ACCESSKEY_MARKER):
+ """Extract the label and accesskey from a label+accesskey string
+
+ The function will also try to ignore &entities; which would obviously not
+ contain accesskeys.
+
+ @type string: Unicode
+ @param string: A string that might contain a label with accesskey marker
+ @type accesskey_marker: Char
+ @param accesskey_marker: The character that is used to prefix an access key
+ """
+ assert isinstance(string, unicode)
+ assert isinstance(accesskey_marker, unicode)
+ assert len(accesskey_marker) == 1
+ if string == u"":
+ return u"", u""
+ accesskey = u""
+ label = string
+ marker_pos = 0
+ while marker_pos >= 0:
+ marker_pos = string.find(accesskey_marker, marker_pos)
+ if marker_pos != -1:
+ marker_pos += 1
+ if accesskey_marker == '&' and XMLEntityPlaceable.regex.match(string[marker_pos-1:]):
+ continue
+ label = string[:marker_pos-1] + string[marker_pos:]
+ accesskey = string[marker_pos]
+ break
+ return label, accesskey
+
+def combine(label, accesskey,
+ accesskey_marker=DEFAULT_ACCESSKEY_MARKER):
+ """Combine a label and and accesskey to form a label+accesskey string
+
+ We place an accesskey marker before the accesskey in the label and this creates a
+ string with the two combined e.g. "File" + "F" = "&File"
+
+ @type label: unicode
+ @param label: a label
+ @type accesskey: unicode char
+ @param accesskey: The accesskey
+ @rtype: unicode or None
+ @return: label+accesskey string or None if uncombineable
+ """
+ assert isinstance(label, unicode)
+ assert isinstance(accesskey, unicode)
+ if len(accesskey) == 0:
+ return None
+ searchpos = 0
+ accesskeypos = -1
+ in_entity = False
+ accesskeyaltcasepos = -1
+ while (accesskeypos < 0) and searchpos < len(label):
+ searchchar = label[searchpos]
+ if searchchar == '&':
+ in_entity = True
+ elif searchchar == ';':
+ in_entity = False
+ else:
+ if not in_entity:
+ if searchchar == accesskey.upper():
+ # always prefer uppercase
+ accesskeypos = searchpos
+ if searchchar == accesskey.lower():
+ # take lower case otherwise...
+ if accesskeyaltcasepos == -1:
+ # only want to remember first altcasepos
+ accesskeyaltcasepos = searchpos
+ # note: we keep on looping through in hope
+ # of exact match
+ searchpos += 1
+ # if we didn't find an exact case match, use an alternate one if available
+ if accesskeypos == -1:
+ accesskeypos = accesskeyaltcasepos
+ # now we want to handle whatever we found...
+ if accesskeypos >= 0:
+ string = label[:accesskeypos] + accesskey_marker + label[accesskeypos:]
+ string = string.encode("UTF-8", "replace")
+ return string
+ else:
+ # can't currently mix accesskey if it's not in label
+ return None
diff --git a/translate-toolkit-1.5.1/translate/convert/convert.py b/translate-toolkit-1.5.1/translate/convert/convert.py
new file mode 100644
index 0000000..9796031
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/convert.py
@@ -0,0 +1,371 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Handles converting of files between formats (used by translate.convert tools)"""
+
+import os.path
+from translate.misc import optrecurse
+# don't import optparse ourselves, get the version from optrecurse
+optparse = optrecurse.optparse
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
+
+class ConvertOptionParser(optrecurse.RecursiveOptionParser, object):
+ """a specialized Option Parser for convertor tools..."""
+ def __init__(self, formats, usetemplates=False, usepots=False, allowmissingtemplate=False, description=None):
+ """construct the specialized Option Parser"""
+ optrecurse.RecursiveOptionParser.__init__(self, formats, usetemplates,
+ allowmissingtemplate=allowmissingtemplate, description=description)
+ self.usepots = usepots
+ self.setpotoption()
+ self.set_usage()
+
+ def add_fuzzy_option(self, default=False):
+ """adds an option to include / exclude fuzzy translations"""
+ fuzzyhelp = "use translations marked fuzzy"
+ nofuzzyhelp = "don't use translations marked fuzzy"
+ if default:
+ fuzzyhelp += " (default)"
+ else:
+ nofuzzyhelp += " (default)"
+ self.add_option("", "--fuzzy", dest="includefuzzy", action="store_true", default=default, help=fuzzyhelp)
+ self.add_option("", "--nofuzzy", dest="includefuzzy", action="store_false", default=default, help=nofuzzyhelp)
+ self.passthrough.append("includefuzzy")
+
+ def add_duplicates_option(self, default="msgctxt"):
+ """adds an option to say what to do with duplicate strings"""
+ self.add_option("", "--duplicates", dest="duplicatestyle", default=default,
+ type="choice", choices=["msgctxt", "merge"],
+ help="what to do with duplicate strings (identical source text): merge, msgctxt (default: '%s')" % default, metavar="DUPLICATESTYLE")
+ self.passthrough.append("duplicatestyle")
+
+ def add_multifile_option(self, default="single"):
+ """adds an option to say how to split the po/pot files"""
+ self.add_option("", "--multifile", dest="multifilestyle", default=default,
+ type="choice", choices=["single", "toplevel", "onefile"],
+ help="how to split po/pot files (single, toplevel or onefile)", metavar="MULTIFILESTYLE")
+ self.passthrough.append("multifilestyle")
+
+ def potifyformat(self, fileformat):
+ """converts a .po to a .pot where required"""
+ if fileformat is None:
+ return fileformat
+ elif fileformat == "po":
+ return "pot"
+ elif fileformat.endswith(os.extsep + "po"):
+ return fileformat + "t"
+ else:
+ return fileformat
+
+ def getformathelp(self, formats):
+ """make a nice help string for describing formats..."""
+ # include implicit pot options...
+ helpformats = []
+ for fileformat in formats:
+ helpformats.append(fileformat)
+ potformat = self.potifyformat(fileformat)
+ if potformat != fileformat:
+ helpformats.append(potformat)
+ return super(ConvertOptionParser, self).getformathelp(helpformats)
+
+ def filterinputformats(self, options):
+ """filters input formats, processing relevant switches in options"""
+ if self.usepots and options.pot:
+ return [self.potifyformat(inputformat) for inputformat in self.inputformats]
+ else:
+ return self.inputformats
+
+ def filteroutputoptions(self, options):
+ """filters output options, processing relevant switches in options"""
+ if self.usepots and options.pot:
+ outputoptions = {}
+ for (inputformat, templateformat), (outputformat, convertor) in self.outputoptions.iteritems():
+ inputformat = self.potifyformat(inputformat)
+ templateformat = self.potifyformat(templateformat)
+ outputformat = self.potifyformat(outputformat)
+ outputoptions[(inputformat, templateformat)] = (outputformat, convertor)
+ return outputoptions
+ else:
+ return self.outputoptions
+
+ def setpotoption(self):
+ """sets the -P/--pot option depending on input/output formats etc"""
+ if self.usepots:
+ potoption = optparse.Option("-P", "--pot", \
+ action="store_true", dest="pot", default=False, \
+ help="output PO Templates (.pot) rather than PO files (.po)")
+ self.define_option(potoption)
+
+ def verifyoptions(self, options):
+ """verifies that the options are valid (required options are present, etc)"""
+ pass
+
+ def run(self, argv=None):
+ """parses the command line options and runs the conversion"""
+ (options, args) = self.parse_args(argv)
+ options.inputformats = self.filterinputformats(options)
+ options.outputoptions = self.filteroutputoptions(options)
+ self.usepsyco(options)
+ self.verifyoptions(options)
+ self.recursiveprocess(options)
+
+def copyinput(inputfile, outputfile, templatefile, **kwargs):
+ """copies the input file to the output file"""
+ outputfile.write(inputfile.read())
+ return True
+
+def copytemplate(inputfile, outputfile, templatefile, **kwargs):
+ """copies the template file to the output file"""
+ outputfile.write(templatefile.read())
+ return True
+
+class Replacer:
+ """an object that knows how to replace strings in files"""
+ def __init__(self, searchstring, replacestring):
+ self.searchstring = searchstring
+ self.replacestring = replacestring
+
+ def doreplace(self, text):
+ """actually replace the text"""
+ if self.searchstring is not None and self.replacestring is not None:
+ return text.replace(self.searchstring, self.replacestring)
+ else:
+ return text
+
+ def searchreplaceinput(self, inputfile, outputfile, templatefile, **kwargs):
+ """copies the input file to the output file, searching and replacing"""
+ outputfile.write(self.doreplace(inputfile.read()))
+ return True
+
+ def searchreplacetemplate(self, inputfile, outputfile, templatefile, **kwargs):
+ """copies the template file to the output file, searching and replacing"""
+ outputfile.write(self.doreplace(templatefile.read()))
+ return True
+
+# archive files need to know how to:
+# - openarchive: creates an archive object for the archivefilename
+# * requires a constructor that takes the filename
+# - iterarchivefile: iterate through the names in the archivefile
+# * requires the default iterator to do this
+# - archivefileexists: check if a given pathname exists inside the archivefile
+# * uses the in operator - requires __contains__ (or will use __iter__ by default)
+# - openarchiveinputfile: returns an open input file from the archive, given the path
+# * requires an archivefile.openinputfile method that takes the pathname
+# - openarchiveoutputfile: returns an open output file from the archive, given the path
+# * requires an archivefile.openoutputfile method that takes the pathname
+
+class ArchiveConvertOptionParser(ConvertOptionParser):
+ """ConvertOptionParser that can handle recursing into single archive files.
+ archiveformats maps extension to class. if the extension doesn't matter, it can be None.
+ if the extension is only valid for input/output/template, it can be given as (extension, filepurpose)"""
+ def __init__(self, formats, usetemplates=False, usepots=False, description=None, archiveformats=None):
+ if archiveformats is None:
+ self.archiveformats = {}
+ else:
+ self.archiveformats = archiveformats
+ self.archiveoptions = {}
+ ConvertOptionParser.__init__(self, formats, usetemplates, usepots, description=description)
+
+ def setarchiveoptions(self, **kwargs):
+ """allows setting options that will always be passed to openarchive"""
+ self.archiveoptions = kwargs
+
+ def isrecursive(self, fileoption, filepurpose='input'):
+ """checks if fileoption is a recursive file"""
+ if self.isarchive(fileoption, filepurpose): return True
+ return super(ArchiveConvertOptionParser, self).isrecursive(fileoption, filepurpose)
+
+ def isarchive(self, fileoption, filepurpose='input'):
+ """returns whether the file option is an archive file"""
+ if not isinstance(fileoption, (str, unicode)):
+ return False
+ mustexist = (filepurpose != 'output')
+ if mustexist and not os.path.isfile(fileoption):
+ return False
+ fileext = self.splitext(fileoption)[1]
+ # if None is in the archive formats, then treat all non-directory inputs as archives
+ return self.getarchiveclass(fileext, filepurpose, os.path.isdir(fileoption)) is not None
+
+ def getarchiveclass(self, fileext, filepurpose, isdir=False):
+ """returns the archiveclass for the given fileext and filepurpose"""
+ archiveclass = self.archiveformats.get(fileext, None)
+ if archiveclass is not None:
+ return archiveclass
+ archiveclass = self.archiveformats.get((fileext, filepurpose), None)
+ if archiveclass is not None:
+ return archiveclass
+ if not isdir:
+ archiveclass = self.archiveformats.get(None, None)
+ if archiveclass is not None:
+ return archiveclass
+ archiveclass = self.archiveformats.get((None, filepurpose), None)
+ if archiveclass is not None:
+ return archiveclass
+ return None
+
+ def openarchive(self, archivefilename, filepurpose, **kwargs):
+ """creates an archive object for the given file"""
+ archiveext = self.splitext(archivefilename)[1]
+ archiveclass = self.getarchiveclass(archiveext, filepurpose, os.path.isdir(archivefilename))
+ archiveoptions = self.archiveoptions.copy()
+ archiveoptions.update(kwargs)
+ return archiveclass(archivefilename, **archiveoptions)
+
+ def recurseinputfiles(self, options):
+ """recurse through archive file / directories and return files to be converted"""
+ if self.isarchive(options.input, 'input'):
+ options.inputarchive = self.openarchive(options.input, 'input')
+ return self.recursearchivefiles(options)
+ else:
+ return super(ArchiveConvertOptionParser, self).recurseinputfiles(options)
+
+ def recursearchivefiles(self, options):
+ """recurse through archive files and convert files"""
+ inputfiles = []
+ for inputpath in options.inputarchive:
+ if self.isexcluded(options, inputpath):
+ continue
+ top, name = os.path.split(inputpath)
+ if not self.isvalidinputname(options, name):
+ continue
+ inputfiles.append(inputpath)
+ return inputfiles
+
+ def openinputfile(self, options, fullinputpath):
+ """opens the input file"""
+ if self.isarchive(options.input, 'input'):
+ return options.inputarchive.openinputfile(fullinputpath)
+ else:
+ return super(ArchiveConvertOptionParser, self).openinputfile(options, fullinputpath)
+
+ def getfullinputpath(self, options, inputpath):
+ """gets the absolute path to an input file"""
+ if self.isarchive(options.input, 'input'):
+ return inputpath
+ else:
+ return os.path.join(options.input, inputpath)
+
+ def opentemplatefile(self, options, fulltemplatepath):
+ """opens the template file (if required)"""
+ if fulltemplatepath is not None:
+ if options.recursivetemplate and self.isarchive(options.template, 'template'):
+ # TODO: deal with different names in input/template archives
+ if fulltemplatepath in options.templatearchive:
+ return options.templatearchive.openinputfile(fulltemplatepath)
+ else:
+ self.warning("missing template file %s" % fulltemplatepath)
+ return super(ArchiveConvertOptionParser, self).opentemplatefile(options, fulltemplatepath)
+
+ def getfulltemplatepath(self, options, templatepath):
+ """gets the absolute path to a template file"""
+ if templatepath is not None and self.usetemplates and options.template:
+ if self.isarchive(options.template, 'template'):
+ return templatepath
+ elif not options.recursivetemplate:
+ return templatepath
+ else:
+ return os.path.join(options.template, templatepath)
+ else:
+ return None
+
+ def templateexists(self, options, templatepath):
+ """returns whether the given template exists..."""
+ if templatepath is not None:
+ if self.isarchive(options.template, 'template'):
+ # TODO: deal with different names in input/template archives
+ return templatepath in options.templatearchive
+ return super(ArchiveConvertOptionParser, self).templateexists(options, templatepath)
+
+ def getfulloutputpath(self, options, outputpath):
+ """gets the absolute path to an output file"""
+ if self.isarchive(options.output, 'output'):
+ return outputpath
+ elif options.recursiveoutput and options.output:
+ return os.path.join(options.output, outputpath)
+ else:
+ return outputpath
+
+ def checkoutputsubdir(self, options, subdir):
+ """checks to see if subdir under options.output needs to be created, creates if neccessary"""
+ if not self.isarchive(options.output, 'output'):
+ super(ArchiveConvertOptionParser, self).checkoutputsubdir(options, subdir)
+
+ def openoutputfile(self, options, fulloutputpath):
+ """opens the output file"""
+ if self.isarchive(options.output, 'output'):
+ outputstream = options.outputarchive.openoutputfile(fulloutputpath)
+ if outputstream is None:
+ self.warning("Could not find where to put %s in output archive; writing to tmp" % fulloutputpath)
+ return StringIO()
+ return outputstream
+ else:
+ return super(ArchiveConvertOptionParser, self).openoutputfile(options, fulloutputpath)
+
+ def inittemplatearchive(self, options):
+ """opens the templatearchive if not already open"""
+ if not self.usetemplates:
+ return
+ if options.template and self.isarchive(options.template, 'template') and not hasattr(options, "templatearchive"):
+ options.templatearchive = self.openarchive(options.template, 'template')
+
+ def initoutputarchive(self, options):
+ """creates an outputarchive if required"""
+ if options.output and self.isarchive(options.output, 'output'):
+ options.outputarchive = self.openarchive(options.output, 'output', mode="w")
+
+ def recursiveprocess(self, options):
+ """recurse through directories and convert files"""
+ if hasattr(options, "multifilestyle"):
+ self.setarchiveoptions(multifilestyle=options.multifilestyle)
+ for filetype in ("input", "output", "template"):
+ allowoption = "allowrecursive%s" % filetype
+ if options.multifilestyle == "onefile" and getattr(options, allowoption, True):
+ setattr(options, allowoption, False)
+ self.inittemplatearchive(options)
+ self.initoutputarchive(options)
+ return super(ArchiveConvertOptionParser, self).recursiveprocess(options)
+
+ def processfile(self, fileprocessor, options, fullinputpath, fulloutputpath, fulltemplatepath):
+ """run an invidividual conversion"""
+ if self.isarchive(options.output, 'output'):
+ inputfile = self.openinputfile(options, fullinputpath)
+ # TODO: handle writing back to same archive as input/template
+ templatefile = self.opentemplatefile(options, fulltemplatepath)
+ outputfile = self.openoutputfile(options, fulloutputpath)
+ passthroughoptions = self.getpassthroughoptions(options)
+ if fileprocessor(inputfile, outputfile, templatefile, **passthroughoptions):
+ if not outputfile.isatty():
+ outputfile.close()
+ return True
+ else:
+ if fulloutputpath and os.path.isfile(fulloutputpath):
+ outputfile.close()
+ os.unlink(fulloutputpath)
+ return False
+ else:
+ return super(ArchiveConvertOptionParser, self).processfile(fileprocessor, options, fullinputpath, fulloutputpath, fulltemplatepath)
+
+def main(argv=None):
+ parser = ArchiveConvertOptionParser({}, description=__doc__)
+ parser.run(argv)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/csv2po b/translate-toolkit-1.5.1/translate/convert/csv2po
new file mode 100755
index 0000000..17192c2
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/csv2po
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2003, 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a comma-separated values (.csv) file to a gettext .po localization file"""
+
+from translate.convert import csv2po
+
+if __name__ == '__main__':
+ csv2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/csv2po.py b/translate-toolkit-1.5.1/translate/convert/csv2po.py
new file mode 100644
index 0000000..9ad3d92
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/csv2po.py
@@ -0,0 +1,200 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2003-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""convert Comma-Separated Value (.csv) files to Gettext PO localization files
+
+See: http://translate.sourceforge.net/wiki/toolkit/csv2po for examples and
+usage instructions
+"""
+
+import sys
+from translate.misc import sparse
+from translate.storage import po
+from translate.storage import csvl10n
+
+def replacestrings(source, *pairs):
+ for orig, new in pairs:
+ source = source.replace(orig, new)
+ return source
+
+def quotecsvstr(source):
+ return '"' + replacestrings(source, ('\\"','"'), ('"','\\"'), ("\\\\'", "\\'"), ('\\\\n', '\\n')) + '"'
+
+def simplify(string):
+ return filter(type(string).isalnum, string)
+ tokens = sparse.SimpleParser().tokenize(string)
+ return " ".join(tokens)
+
+class csv2po:
+ """a class that takes translations from a .csv file and puts them in a .po file"""
+ def __init__(self, templatepo=None, charset=None, duplicatestyle="keep"):
+ """construct the converter..."""
+ self.pofile = templatepo
+ self.charset = charset
+ self.duplicatestyle = duplicatestyle
+ if self.pofile is not None:
+ self.unmatched = 0
+ self.makeindex()
+
+ def makeindex(self):
+ """makes indexes required for searching..."""
+ self.commentindex = {}
+ self.sourceindex = {}
+ self.simpleindex = {}
+ self.duplicatecomments = []
+ for pounit in self.pofile.units:
+ joinedcomment = " ".join(pounit.getlocations())
+ source = pounit.source
+ # the definitive way to match is by source comment (joinedcomment)
+ if joinedcomment in self.commentindex:
+ # unless more than one thing matches...
+ self.duplicatecomments.append(joinedcomment)
+ else:
+ self.commentindex[joinedcomment] = pounit
+ # do simpler matching in case things have been mangled...
+ simpleid = simplify(source)
+ # but check for duplicates
+ if simpleid in self.simpleindex and not (source in self.sourceindex):
+ # keep a list of them...
+ self.simpleindex[simpleid].append(pounit)
+ else:
+ self.simpleindex[simpleid] = [pounit]
+ # also match by standard msgid
+ self.sourceindex[source] = pounit
+ for comment in self.duplicatecomments:
+ if comment in self.commentindex:
+ del self.commentindex[comment]
+
+ def convertunit(self, csvunit):
+ """converts csv unit to po unit"""
+ pounit = po.pounit(encoding="UTF-8")
+ if csvunit.comment:
+ pounit.addlocation(csvunit.comment)
+ pounit.source = csvunit.source
+ pounit.target = csvunit.target
+ return pounit
+
+ def handlecsvunit(self, csvunit):
+ """handles reintegrating a csv unit into the .po file"""
+ if len(csvunit.comment.strip()) > 0 and csvunit.comment in self.commentindex:
+ pounit = self.commentindex[csvunit.comment]
+ elif csvunit.source in self.sourceindex:
+ pounit = self.sourceindex[csvunit.source]
+ elif simplify(csvunit.source) in self.simpleindex:
+ thepolist = self.simpleindex[simplify(csvunit.source)]
+ if len(thepolist) > 1:
+ csvfilename = getattr(self.csvfile, "filename", "(unknown)")
+ matches = "\n ".join(["possible match: " + pounit.source for pounit in thepolist])
+ print >> sys.stderr, "%s - csv entry not found in pofile, multiple matches found:\n location\t%s\n original\t%s\n translation\t%s\n %s" % (csvfilename, csvunit.comment, csvunit.source, csvunit.target, matches)
+ self.unmatched += 1
+ return
+ pounit = thepolist[0]
+ else:
+ csvfilename = getattr(self.csvfile, "filename", "(unknown)")
+ print >> sys.stderr, "%s - csv entry not found in pofile:\n location\t%s\n original\t%s\n translation\t%s" % (csvfilename, csvunit.comment, csvunit.source, csvunit.target)
+ self.unmatched += 1
+ return
+ if pounit.hasplural():
+ # we need to work out whether we matched the singular or the plural
+ singularid = pounit.source.strings[0]
+ pluralid = pounit.source.strings[1]
+ if csvunit.source == singularid:
+ pounit.msgstr[0] = csvunit.target
+ elif csvunit.source == pluralid:
+ pounit.msgstr[1] = csvunit.target
+ elif simplify(csvunit.source) == simplify(singularid):
+ pounit.msgstr[0] = csvunit.target
+ elif simplify(csvunit.source) == simplify(pluralid):
+ pounit.msgstr[1] = csvunit.target
+ else:
+ print >> sys.stderr, "couldn't work out singular or plural: %r, %r, %r" % \
+ (csvunit.source, singularid, pluralid)
+ self.unmatched += 1
+ return
+ else:
+ pounit.target = csvunit.target
+
+ def convertstore(self, thecsvfile):
+ """converts a csvfile to a pofile, and returns it. uses templatepo if given at construction"""
+ self.csvfile = thecsvfile
+ if self.pofile is None:
+ self.pofile = po.pofile()
+ mergemode = False
+ else:
+ mergemode = True
+ if self.pofile.units and self.pofile.units[0].isheader():
+ targetheader = self.pofile.units[0]
+ targetheader.msgstr = [line.replace("CHARSET", "UTF-8").replace("ENCODING", "8bit") for line in targetheader.msgstr]
+ else:
+ targetheader = self.pofile.makeheader(charset="UTF-8", encoding="8bit")
+ targetheader.addnote("extracted from %s" % self.csvfile.filename, "developer")
+ mightbeheader = True
+ for csvunit in self.csvfile.units:
+ if self.charset is not None:
+ csvunit.source = csvunit.source.decode(self.charset)
+ csvunit.target = csvunit.target.decode(self.charset)
+ if mightbeheader:
+ # ignore typical header strings...
+ mightbeheader = False
+ if [item.strip().lower() for item in csvunit.comment, csvunit.source, csvunit.target] == \
+ ["location", "source", "target"]:
+ continue
+ if len(csvunit.comment.strip()) == 0 and csvunit.source.find("Content-Type:") != -1:
+ continue
+ if mergemode:
+ self.handlecsvunit(csvunit)
+ else:
+ pounit = self.convertunit(csvunit)
+ self.pofile.addunit(pounit)
+ self.pofile.removeduplicates(self.duplicatestyle)
+ return self.pofile
+
+def convertcsv(inputfile, outputfile, templatefile, charset=None, columnorder=None, duplicatestyle="msgctxt"):
+ """reads in inputfile using csvl10n, converts using csv2po, writes to outputfile"""
+ inputstore = csvl10n.csvfile(inputfile, fieldnames=columnorder)
+ if templatefile is None:
+ convertor = csv2po(charset=charset, duplicatestyle=duplicatestyle)
+ else:
+ templatestore = po.pofile(templatefile)
+ convertor = csv2po(templatestore, charset=charset, duplicatestyle=duplicatestyle)
+ outputstore = convertor.convertstore(inputstore)
+ if outputstore.isempty():
+ return 0
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {("csv", "po"): ("po", convertcsv), ("csv", "pot"): ("po", convertcsv),
+ ("csv", None): ("po", convertcsv)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ parser.add_option("", "--charset", dest="charset", default=None,
+ help="set charset to decode from csv files", metavar="CHARSET")
+ parser.add_option("", "--columnorder", dest="columnorder", default=None,
+ help="specify the order and position of columns (location,source,target)")
+ parser.add_duplicates_option()
+ parser.passthrough.append("charset")
+ parser.passthrough.append("columnorder")
+ parser.run(argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/csv2tbx b/translate-toolkit-1.5.1/translate/convert/csv2tbx
new file mode 100755
index 0000000..deb9ef6
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/csv2tbx
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a comma-separated values (.csv) file to a .tbx glossary file"""
+
+from translate.convert import csv2tbx
+
+if __name__ == '__main__':
+ csv2tbx.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/csv2tbx.py b/translate-toolkit-1.5.1/translate/convert/csv2tbx.py
new file mode 100644
index 0000000..a1333de
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/csv2tbx.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2006-2007 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""convert Comma-Separated Value (.csv) files to a TermBase eXchange (.tbx) glossary file"""
+
+from translate.misc import sparse
+from translate.storage import tbx
+from translate.storage import csvl10n
+
+class csv2tbx:
+ """a class that takes translations from a .csv file and puts them in a .tbx file"""
+ def __init__(self, charset=None):
+ """construct the converter..."""
+ self.charset = charset
+
+ def convertfile(self, thecsvfile):
+ """converts a csvfile to a tbxfile, and returns it. uses templatepo if given at construction"""
+ mightbeheader = True
+ self.tbxfile = tbx.tbxfile()
+ for thecsv in thecsvfile.units:
+ if mightbeheader:
+ # ignore typical header strings...
+ mightbeheader = False
+ if [item.strip().lower() for item in thecsv.comment, thecsv.source, thecsv.target] == \
+ ["comment", "original", "translation"]:
+ continue
+ if len(thecsv.comment.strip()) == 0 and thecsv.source.find("Content-Type:") != -1:
+ continue
+ term = tbx.tbxunit.buildfromunit(thecsv)
+ # TODO: we might want to get the location or other information from CSV
+ self.tbxfile.addunit(term)
+ return self.tbxfile
+
+def convertcsv(inputfile, outputfile, templatefile, charset=None, columnorder=None):
+ """reads in inputfile using csvl10n, converts using csv2tbx, writes to outputfile"""
+ inputstore = csvl10n.csvfile(inputfile, fieldnames=columnorder)
+ convertor = csv2tbx(charset=charset)
+ outputstore = convertor.convertfile(inputstore)
+ if len(outputstore.units) == 0:
+ return 0
+ outputfile.write(str(outputstore))
+ return 1
+
+def main():
+ from translate.convert import convert
+ formats = {("csv", "tbx"): ("tbx", convertcsv), ("csv", None): ("tbx", convertcsv)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=False, description=__doc__)
+ parser.add_option("", "--charset", dest="charset", default=None,
+ help="set charset to decode from csv files", metavar="CHARSET")
+ parser.add_option("", "--columnorder", dest="columnorder", default=None,
+ help="specify the order and position of columns (comment,source,target)")
+ parser.passthrough.append("charset")
+ parser.passthrough.append("columnorder")
+ parser.run()
+
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/dtd2po.py b/translate-toolkit-1.5.1/translate/convert/dtd2po.py
new file mode 100644
index 0000000..5778945
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/dtd2po.py
@@ -0,0 +1,313 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""script to convert a mozilla .dtd UTF-8 localization format to a
+gettext .po localization file using the po and dtd modules, and the
+dtd2po convertor class which is in this module
+You can convert back to .dtd using po2dtd.py"""
+
+from translate.storage import po
+from translate.storage import dtd
+from translate.misc import quote
+from translate.convert import accesskey as accesskeyfn
+
+def is_css_entity(entity):
+ """Says if the given entity is likely to contain CSS that should not be
+ translated."""
+ if '.' in entity:
+ prefix, suffix = entity.rsplit('.', 1)
+ if suffix in ["height", "width", "unixWidth", "macWidth", "size"] or suffix.startswith("style"):
+ return True
+ return False
+
+class dtd2po:
+ def __init__(self, blankmsgstr=False, duplicatestyle="msgctxt"):
+ self.currentgroup = None
+ self.blankmsgstr = blankmsgstr
+ self.duplicatestyle = duplicatestyle
+
+ def convertcomments(self, thedtd, thepo):
+ entity = quote.rstripeol(thedtd.entity)
+ if len(entity) > 0:
+ thepo.addlocation(thedtd.entity)
+ for commenttype, comment in thedtd.comments:
+ # handle groups
+ if (commenttype == "locgroupstart"):
+ groupcomment = comment.replace('BEGIN','GROUP')
+ self.currentgroup = groupcomment
+ elif (commenttype == "locgroupend"):
+ groupcomment = comment.replace('END','GROUP')
+ self.currentgroup = None
+ # handle automatic comment
+ if commenttype == "automaticcomment":
+ thepo.addnote(comment, origin="developer")
+ # handle normal comments
+ else:
+ thepo.addnote(quote.stripcomment(comment), origin="developer")
+ # handle group stuff
+ if self.currentgroup is not None:
+ thepo.addnote(quote.stripcomment(self.currentgroup), origin="translator")
+ if is_css_entity(entity):
+ thepo.addnote("Do not translate this. Only change the numeric values if you need this dialogue box to appear bigger", origin="developer")
+
+ def convertstrings(self, thedtd, thepo):
+ # extract the string, get rid of quoting
+ unquoted = dtd.unquotefromdtd(thedtd.definition).replace("\r", "")
+ # escape backslashes... but not if they're for a newline
+ # unquoted = unquoted.replace("\\", "\\\\").replace("\\\\n", "\\n")
+ # now split the string into lines and quote them
+ lines = unquoted.split('\n')
+ while lines and not lines[0].strip():
+ del lines[0]
+ while lines and not lines[-1].strip():
+ del lines[-1]
+ # quotes have been escaped already by escapeforpo, so just add the start and end quotes
+ if len(lines) > 1:
+ thepo.source = "\n".join([lines[0].rstrip() + ' '] + \
+ [line.strip() + ' ' for line in lines[1:-1]] + \
+ [lines[-1].lstrip()])
+ elif lines:
+ thepo.source = lines[0]
+ else:
+ thepo.source = ""
+ thepo.target = ""
+
+ def convertunit(self, thedtd):
+ """converts a dtd unit to a po unit, returns None if empty or not for translation"""
+ if thedtd is None:
+ return None
+ if getattr(thedtd, "entityparameter", None) == "SYSTEM":
+ return None
+ thepo = po.pounit(encoding="UTF-8")
+ # remove unwanted stuff
+ for commentnum in range(len(thedtd.comments)):
+ commenttype, locnote = thedtd.comments[commentnum]
+ # if this is a localization note
+ if commenttype == 'locnote':
+ # parse the locnote into the entity and the actual note
+ typeend = quote.findend(locnote,'LOCALIZATION NOTE')
+ # parse the id
+ idstart = locnote.find('(', typeend)
+ if idstart == -1: continue
+ idend = locnote.find(')', idstart+1)
+ entity = locnote[idstart+1:idend].strip()
+ # parse the actual note
+ actualnotestart = locnote.find(':', idend+1)
+ actualnoteend = locnote.find('-->', idend)
+ actualnote = locnote[actualnotestart+1:actualnoteend].strip()
+ # if it's for this entity, process it
+ if thedtd.entity == entity:
+ # if it says don't translate (and nothing more),
+ if actualnote.startswith("DONT_TRANSLATE"):
+ # take out the entity,definition and the DONT_TRANSLATE comment
+ thedtd.entity = ""
+ thedtd.definition = ""
+ del thedtd.comments[commentnum]
+ # finished this for loop
+ break
+ else:
+ # convert it into an automatic comment, to be processed by convertcomments
+ thedtd.comments[commentnum] = ("automaticcomment", actualnote)
+ # do a standard translation
+ self.convertcomments(thedtd, thepo)
+ self.convertstrings(thedtd, thepo)
+ if thepo.isblank() and not thepo.getlocations():
+ return None
+ else:
+ return thepo
+
+ def convertmixedunit(self, labeldtd, accesskeydtd):
+ labelpo = self.convertunit(labeldtd)
+ accesskeypo = self.convertunit(accesskeydtd)
+ if labelpo is None:
+ return accesskeypo
+ if accesskeypo is None:
+ return labelpo
+ thepo = po.pounit(encoding="UTF-8")
+ thepo.addlocations(labelpo.getlocations())
+ thepo.addlocations(accesskeypo.getlocations())
+ thepo.msgidcomment = thepo._extract_msgidcomments() + labelpo._extract_msgidcomments()
+ thepo.msgidcomment = thepo._extract_msgidcomments() + accesskeypo._extract_msgidcomments()
+ thepo.addnote(labelpo.getnotes("developer"), "developer")
+ thepo.addnote(accesskeypo.getnotes("developer"), "developer")
+ thepo.addnote(labelpo.getnotes("translator"), "translator")
+ thepo.addnote(accesskeypo.getnotes("translator"), "translator")
+ # redo the strings from original dtd...
+ label = dtd.unquotefromdtd(labeldtd.definition).decode('UTF-8')
+ accesskey = dtd.unquotefromdtd(accesskeydtd.definition).decode('UTF-8')
+ label = accesskeyfn.combine(label, accesskey)
+ if label is None:
+ return None
+ thepo.source = label
+ thepo.target = ""
+ return thepo
+
+ def findmixedentities(self, thedtdfile):
+ """creates self.mixedentities from the dtd file..."""
+ self.mixedentities = {} # those entities which have a .label/.title and .accesskey combined
+ for entity in thedtdfile.index.keys():
+ for labelsuffix in dtd.labelsuffixes:
+ if entity.endswith(labelsuffix):
+ entitybase = entity[:entity.rfind(labelsuffix)]
+ # see if there is a matching accesskey in this line, making this a
+ # mixed entity
+ for akeytype in dtd.accesskeysuffixes:
+ if thedtdfile.index.has_key(entitybase + akeytype):
+ # add both versions to the list of mixed entities
+ self.mixedentities[entity] = {}
+ self.mixedentities[entitybase+akeytype] = {}
+ # check if this could be a mixed entity (labelsuffix and ".accesskey")
+
+ def convertdtdunit(self, thedtdfile, thedtd, mixbucket="dtd"):
+ """converts a dtd unit from thedtdfile to a po unit, handling mixed entities along the way..."""
+ # keep track of whether accesskey and label were combined
+ if thedtd.entity in self.mixedentities:
+ # use special convertmixed unit which produces one pounit with
+ # both combined for the label and None for the accesskey
+ alreadymixed = self.mixedentities[thedtd.entity].get(mixbucket, None)
+ if alreadymixed:
+ # we are successfully throwing this away...
+ return None
+ elif alreadymixed is None:
+ # depending on what we come across first, work out the label and the accesskey
+ labeldtd, accesskeydtd = None, None
+ labelentity, accesskeyentity = None, None
+ for labelsuffix in dtd.labelsuffixes:
+ if thedtd.entity.endswith(labelsuffix):
+ entitybase = thedtd.entity[:thedtd.entity.rfind(labelsuffix)]
+ for akeytype in dtd.accesskeysuffixes:
+ if thedtdfile.index.has_key(entitybase + akeytype):
+ labelentity, labeldtd = thedtd.entity, thedtd
+ accesskeyentity = labelentity[:labelentity.rfind(labelsuffix)]+akeytype
+ accesskeydtd = thedtdfile.index[accesskeyentity]
+ break
+ else:
+ for akeytype in dtd.accesskeysuffixes:
+ if thedtd.entity.endswith(akeytype):
+ accesskeyentity, accesskeydtd = thedtd.entity, thedtd
+ for labelsuffix in dtd.labelsuffixes:
+ labelentity = accesskeyentity[:accesskeyentity.rfind(akeytype)]+labelsuffix
+ if thedtdfile.index.has_key(labelentity):
+ labeldtd = thedtdfile.index[labelentity]
+ break
+ else:
+ labelentity = None
+ accesskeyentity = None
+ thepo = self.convertmixedunit(labeldtd, accesskeydtd)
+ if thepo is not None:
+ if accesskeyentity is not None:
+ self.mixedentities[accesskeyentity][mixbucket] = True
+ if labelentity is not None:
+ self.mixedentities[labelentity][mixbucket] = True
+ return thepo
+ else:
+ # otherwise the mix failed. add each one separately and remember they weren't mixed
+ if accesskeyentity is not None:
+ self.mixedentities[accesskeyentity][mixbucket] = False
+ if labelentity is not None:
+ self.mixedentities[labelentity][mixbucket] = False
+ return self.convertunit(thedtd)
+
+ def convertstore(self, thedtdfile):
+ thetargetfile = po.pofile()
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit", x_accelerator_marker="&")
+ targetheader.addnote("extracted from %s" % thedtdfile.filename, "developer")
+ thetargetfile.addunit(targetheader)
+ thedtdfile.makeindex()
+ self.findmixedentities(thedtdfile)
+ # go through the dtd and convert each unit
+ for thedtd in thedtdfile.units:
+ if thedtd.isnull():
+ continue
+ thepo = self.convertdtdunit(thedtdfile, thedtd)
+ if thepo is not None:
+ thetargetfile.addunit(thepo)
+ thetargetfile.removeduplicates(self.duplicatestyle)
+ return thetargetfile
+
+ def mergestore(self, origdtdfile, translateddtdfile):
+ thetargetfile = po.pofile()
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit")
+ targetheader.addnote("extracted from %s, %s" % (origdtdfile.filename, translateddtdfile.filename), "developer")
+ thetargetfile.addunit(targetheader)
+ origdtdfile.makeindex()
+ self.findmixedentities(origdtdfile)
+ translateddtdfile.makeindex()
+ self.findmixedentities(translateddtdfile)
+ # go through the dtd files and convert each unit
+ for origdtd in origdtdfile.units:
+ if origdtd.isnull():
+ continue
+ origpo = self.convertdtdunit(origdtdfile, origdtd, mixbucket="orig")
+ if origdtd.entity in self.mixedentities:
+ mixedentitydict = self.mixedentities[origdtd.entity]
+ if "orig" not in mixedentitydict:
+ # this means that the entity is mixed in the translation, but not the original - treat as unmixed
+ mixbucket = "orig"
+ del self.mixedentities[origdtd.entity]
+ elif mixedentitydict["orig"]:
+ # the original entity is already mixed successfully
+ mixbucket = "translate"
+ else:
+ # ??
+ mixbucket = "orig"
+ else:
+ mixbucket = "translate"
+ if origpo is None:
+ # this means its a mixed entity (with accesskey) that's already been dealt with)
+ continue
+ if origdtd.entity in translateddtdfile.index:
+ translateddtd = translateddtdfile.index[origdtd.entity]
+ translatedpo = self.convertdtdunit(translateddtdfile, translateddtd, mixbucket=mixbucket)
+ else:
+ translatedpo = None
+ if origpo is not None:
+ if translatedpo is not None and not self.blankmsgstr:
+ origpo.target = translatedpo.source
+ thetargetfile.addunit(origpo)
+ thetargetfile.removeduplicates(self.duplicatestyle)
+ return thetargetfile
+
+def convertdtd(inputfile, outputfile, templatefile, pot=False, duplicatestyle="msgctxt"):
+ """reads in inputfile and templatefile using dtd, converts using dtd2po, writes to outputfile"""
+ inputstore = dtd.dtdfile(inputfile)
+ convertor = dtd2po(blankmsgstr=pot, duplicatestyle=duplicatestyle)
+ if templatefile is None:
+ outputstore = convertor.convertstore(inputstore)
+ else:
+ templatestore = dtd.dtdfile(templatefile)
+ outputstore = convertor.mergestore(templatestore, inputstore)
+ if outputstore.isempty():
+ return 0
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"dtd": ("po", convertdtd), ("dtd", "dtd"): ("po", convertdtd)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__)
+ parser.add_duplicates_option()
+ parser.passthrough.append("pot")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/html2po b/translate-toolkit-1.5.1/translate/convert/html2po
new file mode 100755
index 0000000..b2293ce
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/html2po
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""extracts localizable strings from HTML files to gettext .po files
+You can merge translated strings back using po2html"""
+
+from translate.convert import html2po
+
+if __name__ == '__main__':
+ html2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/html2po.py b/translate-toolkit-1.5.1/translate/convert/html2po.py
new file mode 100644
index 0000000..2e7e732
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/html2po.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert HTML files to Gettext PO localization files
+
+See: http://translate.sourceforge.net/wiki/toolkit/html2po for examples and
+usage instructions
+"""
+
+from translate.storage import po
+from translate.storage import html
+
+class html2po:
+ def convertfile(self, inputfile, filename, includeheader, includeuntagged=False, duplicatestyle="msgctxt", keepcomments=False):
+ """converts a html file to .po format"""
+ thetargetfile = po.pofile()
+ htmlparser = html.htmlfile(includeuntaggeddata=includeuntagged, inputfile=inputfile)
+ if includeheader:
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit")
+ thetargetfile.addunit(targetheader)
+ for htmlunit in htmlparser.units:
+ thepo = thetargetfile.addsourceunit(htmlunit.source)
+ thepo.addlocations(htmlunit.getlocations())
+ if keepcomments:
+ thepo.addnote(htmlunit.getnotes(), "developer")
+ thetargetfile.removeduplicates(duplicatestyle)
+ return thetargetfile
+
+def converthtml(inputfile, outputfile, templates, includeuntagged=False, pot=False, duplicatestyle="msgctxt", keepcomments=False):
+ """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout"""
+ convertor = html2po()
+ outputfilepos = outputfile.tell()
+ includeheader = outputfilepos == 0
+ outputstore = convertor.convertfile(inputfile, getattr(inputfile, "name", "unknown"), includeheader, includeuntagged, duplicatestyle=duplicatestyle, keepcomments=keepcomments)
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ from translate.misc import stdiotell
+ import sys
+ sys.stdout = stdiotell.StdIOWrapper(sys.stdout)
+ formats = {"html":("po", converthtml), "htm":("po", converthtml), "xhtml":("po", converthtml), None:("po", converthtml)}
+ parser = convert.ConvertOptionParser(formats, usepots=True, description=__doc__)
+ parser.add_option("-u", "--untagged", dest="includeuntagged", default=False, action="store_true",
+ help="include untagged sections")
+ parser.passthrough.append("includeuntagged")
+ parser.add_option("--keepcomments", dest="keepcomments", default=False, action="store_true",
+ help="preserve html comments as translation notes in the output")
+ parser.passthrough.append("keepcomments")
+ parser.add_duplicates_option()
+ parser.passthrough.append("pot")
+ parser.run(argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/ical2po b/translate-toolkit-1.5.1/translate/convert/ical2po
new file mode 100755
index 0000000..448c68b
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/ical2po
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert an iCal file to a gettext .po localization file"""
+
+from translate.convert import ical2po
+
+if __name__ == '__main__':
+ ical2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/ical2po.py b/translate-toolkit-1.5.1/translate/convert/ical2po.py
new file mode 100644
index 0000000..955d456
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/ical2po.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""convert iCal files to Gettext PO localization files"""
+
+import sys
+from translate.storage import po
+from translate.storage import ical
+
+class ical2po:
+ """convert a iCal file to a .po file for handling the translation..."""
+ def convert_store(self, input_store, duplicatestyle="msgctxt"):
+ """converts a iCal file to a .po file..."""
+ output_store = po.pofile()
+ output_header = output_store.makeheader(charset="UTF-8", encoding="8bit")
+ output_header.addnote("extracted from %s" % input_store.filename, "developer")
+ output_store.addunit(output_header)
+ for input_unit in input_store.units:
+ output_unit = self.convert_unit(input_unit, "developer")
+ if output_unit is not None:
+ output_store.addunit(output_unit)
+ output_store.removeduplicates(duplicatestyle)
+ return output_store
+
+ def merge_store(self, template_store, input_store, blankmsgstr=False, duplicatestyle="msgctxt"):
+ """converts two iCal files to a .po file..."""
+ output_store = po.pofile()
+ output_header = output_store.makeheader(charset="UTF-8", encoding="8bit")
+ output_header.addnote("extracted from %s, %s" % (template_store.filename, input_store.filename), "developer")
+ output_store.addunit(output_header)
+ input_store.makeindex()
+ for template_unit in template_store.units:
+ origpo = self.convert_unit(template_unit, "developer")
+ # try and find a translation of the same name...
+ template_unit_name = "".join(template_unit.getlocations())
+ if template_unit_name in input_store.locationindex:
+ translatedini = input_store.locationindex[template_unit_name]
+ translatedpo = self.convert_unit(translatedini, "translator")
+ else:
+ translatedpo = None
+ # if we have a valid po unit, get the translation and add it...
+ if origpo is not None:
+ if translatedpo is not None and not blankmsgstr:
+ origpo.target = translatedpo.source
+ output_store.addunit(origpo)
+ elif translatedpo is not None:
+ print >> sys.stderr, "error converting original iCal definition %s" % origini.name
+ output_store.removeduplicates(duplicatestyle)
+ return output_store
+
+ def convert_unit(self, input_unit, commenttype):
+ """Converts a .ini unit to a .po unit. Returns None if empty
+ or not for translation."""
+ if input_unit is None:
+ return None
+ # escape unicode
+ output_unit = po.pounit(encoding="UTF-8")
+ output_unit.addlocation("".join(input_unit.getlocations()))
+ output_unit.addnote(input_unit.getnotes("developer"), "developer")
+ output_unit.source = input_unit.source
+ output_unit.target = ""
+ return output_unit
+
+def convertical(input_file, output_file, template_file, pot=False, duplicatestyle="msgctxt"):
+ """Reads in L{input_file} using iCal, converts using L{ical2po}, writes to L{output_file}"""
+ input_store = ical.icalfile(input_file)
+ convertor = ical2po()
+ if template_file is None:
+ output_store = convertor.convert_store(input_store, duplicatestyle=duplicatestyle)
+ else:
+ template_store = ical.icalfile(template_file)
+ output_store = convertor.merge_store(template_store, input_store, blankmsgstr=pot, duplicatestyle=duplicatestyle)
+ if output_store.isempty():
+ return 0
+ output_file.write(str(output_store))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"ics": ("po", convertical), ("ics", "ics"): ("po", convertical)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__)
+ parser.add_duplicates_option()
+ parser.passthrough.append("pot")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/ini2po b/translate-toolkit-1.5.1/translate/convert/ini2po
new file mode 100755
index 0000000..32976c2
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/ini2po
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2002, 2003 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a .ini file to a gettext .po localization file"""
+
+from translate.convert import ini2po
+
+if __name__ == '__main__':
+ ini2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/ini2po.py b/translate-toolkit-1.5.1/translate/convert/ini2po.py
new file mode 100644
index 0000000..7b1dbd8
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/ini2po.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""convert .ini files to Gettext PO localization files"""
+
+import sys
+from translate.storage import po
+from translate.storage import ini
+
+class ini2po:
+ """convert a .ini file to a .po file for handling the translation..."""
+ def convert_store(self, input_store, duplicatestyle="msgctxt"):
+ """converts a .ini file to a .po file..."""
+ output_store = po.pofile()
+ output_header = output_store.makeheader(charset="UTF-8", encoding="8bit")
+ output_header.addnote("extracted from %s" % input_store.filename, "developer")
+ output_store.addunit(output_header)
+ for input_unit in input_store.units:
+ output_unit = self.convert_unit(input_unit, "developer")
+ if output_unit is not None:
+ output_store.addunit(output_unit)
+ output_store.removeduplicates(duplicatestyle)
+ return output_store
+
+ def merge_store(self, template_store, input_store, blankmsgstr=False, duplicatestyle="msgctxt"):
+ """converts two .ini files to a .po file..."""
+ output_store = po.pofile()
+ output_header = output_store.makeheader(charset="UTF-8", encoding="8bit")
+ output_header.addnote("extracted from %s, %s" % (template_store.filename, input_store.filename), "developer")
+ output_store.addunit(output_header)
+ input_store.makeindex()
+ for template_unit in template_store.units:
+ origpo = self.convert_unit(template_unit, "developer")
+ # try and find a translation of the same name...
+ template_unit_name = "".join(template_unit.getlocations())
+ if template_unit_name in input_store.locationindex:
+ translatedini = input_store.locationindex[template_unit_name]
+ translatedpo = self.convert_unit(translatedini, "translator")
+ else:
+ translatedpo = None
+ # if we have a valid po unit, get the translation and add it...
+ if origpo is not None:
+ if translatedpo is not None and not blankmsgstr:
+ origpo.target = translatedpo.source
+ output_store.addunit(origpo)
+ elif translatedpo is not None:
+ print >> sys.stderr, "error converting original ini definition %s" % origini.name
+ output_store.removeduplicates(duplicatestyle)
+ return output_store
+
+ def convert_unit(self, input_unit, commenttype):
+ """Converts a .ini unit to a .po unit. Returns None if empty
+ or not for translation."""
+ if input_unit is None:
+ return None
+ # escape unicode
+ output_unit = po.pounit(encoding="UTF-8")
+ output_unit.addlocation("".join(input_unit.getlocations()))
+ output_unit.source = input_unit.source
+ output_unit.target = ""
+ return output_unit
+
+def convertini(input_file, output_file, template_file, pot=False, duplicatestyle="msgctxt", dialect="default"):
+ """Reads in L{input_file} using ini, converts using L{ini2po}, writes to L{output_file}"""
+ input_store = ini.inifile(input_file, dialect=dialect)
+ convertor = ini2po()
+ if template_file is None:
+ output_store = convertor.convert_store(input_store, duplicatestyle=duplicatestyle)
+ else:
+ template_store = ini.inifile(template_file, dialect=dialect)
+ output_store = convertor.merge_store(template_store, input_store, blankmsgstr=pot, duplicatestyle=duplicatestyle)
+ if output_store.isempty():
+ return 0
+ output_file.write(str(output_store))
+ return 1
+
+def convertisl(input_file, output_file, template_file, pot=False, duplicatestyle="msgctxt", dialect="inno"):
+ return convertini(input_file, output_file, template_file, pot=False, duplicatestyle="msgctxt", dialect=dialect)
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {
+ "ini": ("po", convertini), ("ini", "ini"): ("po", convertini),
+ "isl": ("po", convertisl), ("isl", "isl"): ("po", convertisl),
+ "iss": ("po", convertisl), ("iss", "iss"): ("po", convertisl),
+ }
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__)
+ parser.add_duplicates_option()
+ parser.passthrough.append("pot")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/moz2po b/translate-toolkit-1.5.1/translate/convert/moz2po
new file mode 100755
index 0000000..da9a148
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/moz2po
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Converts Mozilla .dtd and .properties files to Gettext .po files"""
+
+from translate.convert import moz2po
+
+if __name__ == '__main__':
+ moz2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/moz2po.py b/translate-toolkit-1.5.1/translate/convert/moz2po.py
new file mode 100644
index 0000000..903a6d4
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/moz2po.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""convert Mozilla .dtd and .properties files to Gettext PO localization files
+
+See: http://translate.sourceforge.net/wiki/toolkit/moz2po for examples and
+usage instructions
+"""
+
+from translate.convert import dtd2po
+from translate.convert import prop2po
+from translate.convert import mozfunny2prop
+from translate.storage import xpi
+from translate.convert import convert
+
+def main(argv=None):
+ formats = {(None, "*"): ("*", convert.copytemplate),
+ ("*", "*"): ("*", convert.copyinput),
+ "*": ("*", convert.copyinput)}
+ # handle formats that convert to .po files
+ converters = [("dtd", dtd2po.convertdtd), ("properties", prop2po.convertmozillaprop),
+ ("it", mozfunny2prop.it2po), ("ini", mozfunny2prop.ini2po), ("inc", mozfunny2prop.inc2po)]
+ for format, converter in converters:
+ formats[(format, format)] = (format + ".po", converter)
+ formats[format] = (format + ".po", converter)
+ # handle search and replace
+ replacer = convert.Replacer("en-US", "${locale}")
+ for replaceformat in ("js", "rdf", "manifest"):
+ formats[(None, replaceformat)] = (replaceformat, replacer.searchreplacetemplate)
+ formats[(replaceformat, replaceformat)] = (replaceformat, replacer.searchreplaceinput)
+ formats[replaceformat] = (replaceformat, replacer.searchreplaceinput)
+ parser = convert.ArchiveConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__, archiveformats={"xpi": xpi.XpiFile})
+ parser.add_duplicates_option()
+ parser.passthrough.append("pot")
+ parser.run(argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/mozfunny2prop.py b/translate-toolkit-1.5.1/translate/convert/mozfunny2prop.py
new file mode 100644
index 0000000..0a7399a
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/mozfunny2prop.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2005, 2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""converts funny mozilla files to properties files"""
+
+import string
+from translate.misc import quote
+from translate.convert import prop2po
+from translate.misc.wStringIO import StringIO
+
+def inc2prop(lines):
+ """convert a .inc file with #defines in it to a properties file"""
+ yield "# converted from #defines file\n"
+ for line in lines:
+ line = line.decode("utf-8")
+ if line.startswith("# "):
+ commented = True
+ line = line.replace("# ", "", 1)
+ else:
+ commented = False
+ if not line.strip():
+ yield line
+ elif line.startswith("#define"):
+ parts = string.split(line.replace("#define", "", 1).strip(), maxsplit=1)
+ if not parts:
+ continue
+ if len(parts) == 1:
+ key, value = parts[0], ""
+ else:
+ key, value = parts
+ # special case: uncomment MOZ_LANGPACK_CONTRIBUTORS
+ if key == "MOZ_LANGPACK_CONTRIBUTORS":
+ commented = False
+ if commented:
+ yield "# "
+ yield "%s = %s\n" % (key, value)
+ else:
+ if commented:
+ yield "# "
+ yield line
+
+def it2prop(lines, encoding="cp1252"):
+ """convert a pseudo-properties .it file to a conventional properties file"""
+ yield "# converted from pseudo-properties .it file\n"
+ # differences: ; instead of # for comments
+ # [section] titles that we replace with # section: comments
+ for line in lines:
+ line = line.decode(encoding)
+ if not line.strip():
+ yield line
+ elif line.lstrip().startswith(";"):
+ yield line.replace(";", "#", 1)
+ elif line.lstrip().startswith("[") and line.rstrip().endswith("]"):
+ yield "# section: "+line
+ else:
+ yield line
+
+def funny2prop(lines, itencoding="cp1252"):
+ hashstarts = len([line for line in lines if line.startswith("#")])
+ if hashstarts:
+ for line in inc2prop(lines):
+ yield line
+ else:
+ for line in it2prop(lines, encoding=itencoding):
+ yield line
+
+def inc2po(inputfile, outputfile, templatefile, encoding=None, pot=False, duplicatestyle="msgctxt"):
+ """wraps prop2po but converts input/template files to properties first"""
+ inputlines = inputfile.readlines()
+ inputproplines = [line for line in inc2prop(inputlines)]
+ inputpropfile = StringIO("".join(inputproplines))
+ if templatefile is not None:
+ templatelines = templatefile.readlines()
+ templateproplines = [line for line in inc2prop(templatelines)]
+ templatepropfile = StringIO("".join(templateproplines))
+ else:
+ templatepropfile = None
+ return prop2po.convertprop(inputpropfile, outputfile, templatepropfile, personality="mozilla", pot=pot, duplicatestyle=duplicatestyle)
+
+def it2po(inputfile, outputfile, templatefile, encoding="cp1252", pot=False, duplicatestyle="msgctxt"):
+ """wraps prop2po but converts input/template files to properties first"""
+ inputlines = inputfile.readlines()
+ inputproplines = [line for line in it2prop(inputlines, encoding=encoding)]
+ inputpropfile = StringIO("".join(inputproplines))
+ if templatefile is not None:
+ templatelines = templatefile.readlines()
+ templateproplines = [line for line in it2prop(templatelines, encoding=encoding)]
+ templatepropfile = StringIO("".join(templateproplines))
+ else:
+ templatepropfile = None
+ return prop2po.convertprop(inputpropfile, outputfile, templatepropfile, personality="mozilla", pot=pot, duplicatestyle=duplicatestyle)
+
+def ini2po(inputfile, outputfile, templatefile, encoding="UTF-8", pot=False, duplicatestyle="msgctxt"):
+ return it2po(inputfile=inputfile, outputfile=outputfile, templatefile=templatefile, encoding=encoding, pot=pot, duplicatestyle=duplicatestyle)
+
+def main(argv=None):
+ import sys
+ lines = sys.stdin.readlines()
+ for line in funny2prop(lines):
+ sys.stdout.write(line)
+
+if __name__ == "__main__":
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/odf2xliff b/translate-toolkit-1.5.1/translate/convert/odf2xliff
new file mode 100755
index 0000000..5d902d1
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/odf2xliff
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Extracts localizable strings from OpenDocument files to XLIFF files
+
+Files supported include:
+- .odt (Wordprocessor documents)
+- .ods (Spreadsheets)
+- .odp (Presentations)
+- .sxw (old OpenOffice.org 1.0 Wordprocessor documents)
+"""
+
+from translate.convert import odf2xliff
+
+if __name__ == '__main__':
+ odf2xliff.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/odf2xliff.py b/translate-toolkit-1.5.1/translate/convert/odf2xliff.py
new file mode 100644
index 0000000..8b14c17
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/odf2xliff.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert OpenDocument (ODF) files to XLIFF localization files"""
+
+# Import from ttk
+from translate.storage import factory
+
+from translate.misc.contextlib import contextmanager, nested
+from translate.misc.context import with_
+from translate.storage import odf_io
+
+def convertodf(inputfile, outputfile, templates, engine):
+ """reads in stdin using fromfileclass, converts using convertorclass,
+ writes to stdout
+ """
+
+ def translate_toolkit_implementation(store):
+ import cStringIO
+ import zipfile
+
+ from translate.storage.xml_extract import extract
+ from translate.storage import odf_shared
+
+ contents = odf_io.open_odf(inputfile)
+ for data in contents.values():
+ parse_state = extract.ParseState(odf_shared.no_translate_content_elements,
+ odf_shared.inline_elements)
+ extract.build_store(cStringIO.StringIO(data), store, parse_state)
+
+ def itools_implementation(store):
+ from itools.handlers import get_handler
+ from itools.gettext.po import encode_source
+ import itools.odf
+
+ filename = getattr(inputfile, 'name', 'unkown')
+ handler = get_handler(filename)
+
+ try:
+ get_units = handler.get_units
+ except AttributeError:
+ message = 'error: the file "%s" could not be processed'
+ raise AttributeError, message % filename
+
+ # Make the XLIFF file
+ for source, context, line in get_units():
+ source = encode_source(source)
+ unit = store.UnitClass(source)
+ store.addunit(unit)
+
+ @contextmanager
+ def store_context():
+ store = factory.getobject(outputfile)
+ try:
+ store.setfilename(store.getfilenode('NoName'), inputfile.name)
+ except:
+ print "couldn't set origin filename"
+ yield store
+ store.save()
+
+ def with_block(store):
+ if engine == "toolkit":
+ translate_toolkit_implementation(store)
+ else:
+ itools_implementation(store)
+
+ # Since the convertoptionsparser will give us an open file, we risk that
+ # it could have been opened in non-binary mode on Windows, and then we'll
+ # have problems, so let's make sure we have what we want.
+ inputfile.close()
+ inputfile = file(inputfile.name, mode='rb')
+ with_(store_context(), with_block)
+ return True
+
+
+def main(argv=None):
+ def add_options(parser):
+ parser.add_option("", "--engine", dest="engine", default="toolkit",
+ type="choice", choices=["toolkit", "itools"],
+ help="""Choose whether itools (--engine=itools) or the translate toolkit (--engine=toolkit)
+ should be used as the engine to convert an ODF file to an XLIFF file.""")
+ parser.passthrough = ['engine']
+ return parser
+
+ from translate.convert import convert
+ # For formats see OpenDocument 1.2 draft 7 Appendix C
+ formats = {"sxw": ("xlf", convertodf),
+ "odt": ("xlf", convertodf), # Text
+ "ods": ("xlf", convertodf), # Spreadsheet
+ "odp": ("xlf", convertodf), # Presentation
+ "odg": ("xlf", convertodf), # Drawing
+ "odc": ("xlf", convertodf), # Chart
+ "odf": ("xlf", convertodf), # Formula
+ "odi": ("xlf", convertodf), # Image
+ "odm": ("xlf", convertodf), # Master Document
+ "ott": ("xlf", convertodf), # Text template
+ "ots": ("xlf", convertodf), # Spreadsheet template
+ "otp": ("xlf", convertodf), # Presentation template
+ "otg": ("xlf", convertodf), # Drawing template
+ "otc": ("xlf", convertodf), # Chart template
+ "otf": ("xlf", convertodf), # Formula template
+ "oti": ("xlf", convertodf), # Image template
+ "oth": ("xlf", convertodf), # Web page template
+ }
+ parser = convert.ConvertOptionParser(formats, description=__doc__)
+ add_options(parser)
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/oo2po b/translate-toolkit-1.5.1/translate/convert/oo2po
new file mode 100755
index 0000000..2c96f47
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/oo2po
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+#
+# Copyright 2002-2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Converts OpenOffice.org exported .oo files to Gettext .po files"""
+
+from translate.convert import oo2po
+
+if __name__ == '__main__':
+ oo2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/oo2po.py b/translate-toolkit-1.5.1/translate/convert/oo2po.py
new file mode 100644
index 0000000..e6a9de5
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/oo2po.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2003-2008 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert an OpenOffice.org (SDF) localization file to Gettext PO localization files
+
+See: http://translate.sourceforge.net/wiki/toolkit/oo2po for examples and
+usage instructions
+"""
+
+import os
+import sys
+from translate.storage import po
+from translate.storage import oo
+
+# TODO: support using one GSI file as template, another as input (for when English is in one and translation in another)
+
+class oo2po:
+ def __init__(self, sourcelanguage, targetlanguage, blankmsgstr=False, long_keys=False):
+ """construct an oo2po converter for the specified languages"""
+ self.sourcelanguage = sourcelanguage
+ self.targetlanguage = targetlanguage
+ self.blankmsgstr = blankmsgstr
+ self.long_keys = long_keys
+
+ def maketargetunit(self, part1, part2, translators_comment, key, subkey):
+ """makes a base unit (.po or XLIFF) out of a subkey of two parts"""
+ #TODO: Do better
+ text1 = getattr(part1, subkey)
+ if text1 == "":
+ return None
+ text2 = getattr(part2, subkey)
+
+ unit = po.pounit(text1.decode('utf-8'), encoding="UTF-8")
+ unit.target = text2.decode('utf-8')
+ unit.addlocation(key + "." + subkey)
+ if getattr(translators_comment, subkey).strip() != "":
+ unit.addnote(getattr(translators_comment, subkey), origin="developer")
+ return unit
+
+ def convertelement(self, theoo):
+ """convert an oo element into a list of base units (.po or XLIFF)"""
+ if self.sourcelanguage in theoo.languages:
+ part1 = theoo.languages[self.sourcelanguage]
+ else:
+ print >> sys.stderr, "/".join(theoo.lines[0].getkey()), "language not found: %s" % (self.sourcelanguage)
+ return []
+ if self.blankmsgstr:
+ # use a blank part2
+ part2 = oo.ooline()
+ else:
+ if self.targetlanguage in theoo.languages:
+ part2 = theoo.languages[self.targetlanguage]
+ else:
+ # if the language doesn't exist, the translation is missing ... so make it blank
+ part2 = oo.ooline()
+ if "x-comment" in theoo.languages:
+ translators_comment = theoo.languages["x-comment"]
+ else:
+ translators_comment = oo.ooline()
+ key = oo.makekey(part1.getkey(), self.long_keys)
+ unitlist = []
+ for subkey in ("text", "quickhelptext", "title"):
+ unit = self.maketargetunit(part1, part2, translators_comment, key, subkey)
+ if unit is not None:
+ unitlist.append(unit)
+ return unitlist
+
+ def convertstore(self, theoofile, duplicatestyle="msgctxt"):
+ """converts an entire oo file to a base class format (.po or XLIFF)"""
+ thetargetfile = po.pofile()
+ # create a header for the file
+ bug_url = 'http://qa.openoffice.org/issues/enter_bug.cgi' + ('''?subcomponent=ui&comment=&short_desc=Localization issue in file: %(filename)s&component=l10n&form_name=enter_issue''' % {"filename": theoofile.filename}).replace(" ", "%20").replace(":", "%3A")
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit", x_accelerator_marker="~", report_msgid_bugs_to=bug_url)
+ targetheader.addnote("extracted from %s" % theoofile.filename, "developer")
+ thetargetfile.addunit(targetheader)
+ thetargetfile.setsourcelanguage(self.sourcelanguage)
+ thetargetfile.settargetlanguage(self.targetlanguage)
+ # go through the oo and convert each element
+ for theoo in theoofile.units:
+ unitlist = self.convertelement(theoo)
+ for unit in unitlist:
+ thetargetfile.addunit(unit)
+ thetargetfile.removeduplicates(duplicatestyle)
+ return thetargetfile
+
+def verifyoptions(options):
+ """verifies the commandline options"""
+ if not options.pot and not options.targetlanguage:
+ raise ValueError("You must specify the target language unless generating POT files (-P)")
+
+def convertoo(inputfile, outputfile, templates, pot=False, sourcelanguage=None, targetlanguage=None, duplicatestyle="msgid_comment", multifilestyle="single"):
+ """reads in stdin using inputstore class, converts using convertorclass, writes to stdout"""
+ inputstore = oo.oofile()
+ if hasattr(inputfile, "filename"):
+ inputfilename = inputfile.filename
+ else:
+ inputfilename = "(input file name not known)"
+ inputstore.filename = inputfilename
+ inputstore.parse(inputfile.read())
+ if not sourcelanguage:
+ testlangtype = targetlanguage or (inputstore and inputstore.languages[0]) or ""
+ if testlangtype.isdigit():
+ sourcelanguage = "01"
+ else:
+ sourcelanguage = "en-US"
+ if not sourcelanguage in inputstore.languages:
+ print >> sys.stderr, "Warning: sourcelanguage '%s' not found in inputfile '%s' (contains %s)" % (sourcelanguage, inputfilename, ", ".join(inputstore.languages))
+ if targetlanguage and targetlanguage not in inputstore.languages:
+ print >> sys.stderr, "Warning: targetlanguage '%s' not found in inputfile '%s' (contains %s)" % (targetlanguage, inputfilename, ", ".join(inputstore.languages))
+ convertor = oo2po(sourcelanguage, targetlanguage, blankmsgstr=pot, long_keys=multifilestyle!="single")
+ outputstore = convertor.convertstore(inputstore, duplicatestyle)
+ if outputstore.isempty():
+ return 0
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"oo":("po", convertoo), "sdf":("po", convertoo)}
+ # always treat the input as an archive unless it is a directory
+ archiveformats = {(None, "input"): oo.oomultifile}
+ parser = convert.ArchiveConvertOptionParser(formats, usepots=True, description=__doc__, archiveformats=archiveformats)
+ parser.add_option("-l", "--language", dest="targetlanguage", default=None,
+ help="set target language to extract from oo file (e.g. af-ZA)", metavar="LANG")
+ parser.add_option("", "--source-language", dest="sourcelanguage", default=None,
+ help="set source language code (default en-US)", metavar="LANG")
+ parser.add_option("", "--nonrecursiveinput", dest="allowrecursiveinput", default=True, action="store_false", help="don't treat the input oo as a recursive store")
+ parser.add_duplicates_option()
+ parser.add_multifile_option()
+ parser.passthrough.append("pot")
+ parser.passthrough.append("sourcelanguage")
+ parser.passthrough.append("targetlanguage")
+ parser.verifyoptions = verifyoptions
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/oo2xliff b/translate-toolkit-1.5.1/translate/convert/oo2xliff
new file mode 100755
index 0000000..cf11570
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/oo2xliff
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2002-2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Converts OpenOffice.org exported .oo files to xliff files"""
+
+from translate.convert import oo2xliff
+
+if __name__ == '__main__':
+ oo2xliff.main()
diff --git a/translate-toolkit-1.5.1/translate/convert/oo2xliff.py b/translate-toolkit-1.5.1/translate/convert/oo2xliff.py
new file mode 100644
index 0000000..474ba55
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/oo2xliff.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2003-2008 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert an OpenOffice.org (SDF) localization file to XLIFF localization files
+
+User documentation: http://translate.sourceforge.net/wiki/toolkit/oo2po
+"""
+
+import os
+import sys
+from translate.storage import xliff
+from translate.storage import oo
+
+# TODO: support using one GSI file as template, another as input (for when English is in one and translation in another)
+
+class oo2xliff:
+ def __init__(self, sourcelanguage, targetlanguage, blankmsgstr=False, long_keys=False):
+ """construct an oo2xliff converter for the specified languages"""
+ self.sourcelanguage = sourcelanguage
+ self.targetlanguage = targetlanguage
+ self.blankmsgstr = blankmsgstr
+ self.long_keys = long_keys
+
+ def maketargetunit(self, part1, part2, translators_comment, key, subkey):
+ """makes a base unit (.po or XLIFF) out of a subkey of two parts"""
+ #TODO: Do better
+ text1 = getattr(part1, subkey)
+ if text1 == "":
+ return None
+ text2 = getattr(part2, subkey)
+
+ unit = xliff.xliffunit(text1)
+ unit.target = text2
+ if unit.target:
+ unit.markfuzzy(False)
+ else:
+ unit.markfuzzy(True)
+ unit.addlocation(key + "." + subkey)
+ if getattr(translators_comment, subkey).strip() != "":
+ unit.addnote(getattr(translators_comment, subkey), origin="developer")
+ return unit
+
+ def convertelement(self, theoo):
+ """convert an oo element into a list of base units (.po or XLIFF)"""
+ if self.sourcelanguage in theoo.languages:
+ part1 = theoo.languages[self.sourcelanguage]
+ else:
+ print >> sys.stderr, "/".join(theoo.lines[0].getkey()), "language not found: %s" % (self.sourcelanguage)
+ return []
+ if self.blankmsgstr:
+ # use a blank part2
+ part2 = oo.ooline()
+ else:
+ if self.targetlanguage in theoo.languages:
+ part2 = theoo.languages[self.targetlanguage]
+ else:
+ # if the language doesn't exist, the translation is missing ... so make it blank
+ part2 = oo.ooline()
+ if "x-comment" in theoo.languages:
+ translators_comment = theoo.languages["x-comment"]
+ else:
+ translators_comment = oo.ooline()
+ key = oo.makekey(part1.getkey(), self.long_keys)
+ unitlist = []
+ for subkey in ("text", "quickhelptext", "title"):
+ unit = self.maketargetunit(part1, part2, translators_comment, key, subkey)
+ if unit is not None:
+ unitlist.append(unit)
+ return unitlist
+
+ def convertstore(self, theoofile, duplicatestyle="msgctxt"):
+ """converts an entire oo file to a base class format (.po or XLIFF)"""
+ thetargetfile = xliff.xlifffile()
+ thetargetfile.setsourcelanguage(self.sourcelanguage)
+ thetargetfile.settargetlanguage(self.targetlanguage)
+ # create a header for the file
+ bug_url = 'http://qa.openoffice.org/issues/enter_bug.cgi' + ('''?subcomponent=ui&comment=&short_desc=Localization issue in file: %(filename)s&component=l10n&form_name=enter_issue''' % {"filename": theoofile.filename}).replace(" ", "%20").replace(":", "%3A")
+ # go through the oo and convert each element
+ for theoo in theoofile.units:
+ unitlist = self.convertelement(theoo)
+ for unit in unitlist:
+ thetargetfile.addunit(unit)
+ return thetargetfile
+
+def verifyoptions(options):
+ """verifies the commandline options"""
+ if not options.targetlanguage:
+ raise ValueError("You must specify the target language.")
+
+def convertoo(inputfile, outputfile, templates, pot=False, sourcelanguage=None, targetlanguage=None, duplicatestyle="msgctxt", multifilestyle="single"):
+ """reads in stdin using inputstore class, converts using convertorclass, writes to stdout"""
+ inputstore = oo.oofile()
+ if hasattr(inputfile, "filename"):
+ inputfilename = inputfile.filename
+ else:
+ inputfilename = "(input file name not known)"
+ inputstore.filename = inputfilename
+ inputstore.parse(inputfile.read())
+ if not sourcelanguage:
+ testlangtype = targetlanguage or (inputstore and inputstore.languages[0]) or ""
+ if testlangtype.isdigit():
+ sourcelanguage = "01"
+ else:
+ sourcelanguage = "en-US"
+ if not sourcelanguage in inputstore.languages:
+ print >> sys.stderr, "Warning: sourcelanguage '%s' not found in inputfile '%s' (contains %s)" % (sourcelanguage, inputfilename, ", ".join(inputstore.languages))
+ if not pot and targetlanguage and targetlanguage not in inputstore.languages:
+ print >> sys.stderr, "Warning: targetlanguage '%s' not found in inputfile '%s' (contains %s)" % (targetlanguage, inputfilename, ", ".join(inputstore.languages))
+ convertor = oo2xliff(sourcelanguage, targetlanguage, blankmsgstr=pot, long_keys=multifilestyle!="single")
+ outputstore = convertor.convertstore(inputstore, duplicatestyle)
+ if outputstore.isempty():
+ return 0
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"oo":("xlf", convertoo), "sdf":("xlf", convertoo)}
+ # always treat the input as an archive unless it is a directory
+ archiveformats = {(None, "input"): oo.oomultifile}
+ parser = convert.ArchiveConvertOptionParser(formats, usepots=False, description=__doc__, archiveformats=archiveformats)
+ parser.add_option("-l", "--language", dest="targetlanguage", default=None,
+ help="set target language to extract from oo file (e.g. af-ZA)", metavar="LANG")
+ parser.add_option("", "--source-language", dest="sourcelanguage", default=None,
+ help="set source language code (default en-US)", metavar="LANG")
+ parser.add_option("", "--nonrecursiveinput", dest="allowrecursiveinput", default=True, action="store_false", help="don't treat the input oo as a recursive store")
+ parser.add_duplicates_option()
+ parser.add_multifile_option()
+ parser.passthrough.append("sourcelanguage")
+ parser.passthrough.append("targetlanguage")
+ parser.verifyoptions = verifyoptions
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/php2po b/translate-toolkit-1.5.1/translate/convert/php2po
new file mode 100755
index 0000000..50edf91
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/php2po
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""extracts localizable strings from PHP files to gettext .po files
+You can merge translated strings back using po2php"""
+
+from translate.convert import php2po
+
+if __name__ == '__main__':
+ php2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/php2po.py b/translate-toolkit-1.5.1/translate/convert/php2po.py
new file mode 100644
index 0000000..9ffc412
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/php2po.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""convert PHP localization files to Gettext PO localization files
+
+See: http://translate.sourceforge.net/wiki/toolkit/php2po for examples and
+usage instructions
+"""
+
+import sys
+from translate.storage import po
+from translate.storage import php
+
+class php2po:
+ """convert a .php file to a .po file for handling the translation..."""
+ def convertstore(self, inputstore, duplicatestyle="msgctxt"):
+ """converts a .php file to a .po file..."""
+ outputstore = po.pofile()
+ outputheader = outputstore.makeheader(charset="UTF-8", encoding="8bit")
+ outputheader.addnote("extracted from %s" % inputstore.filename, "developer")
+ outputstore.addunit(outputheader)
+ for inputunit in inputstore.units:
+ outputunit = self.convertunit(inputunit, "developer")
+ if outputunit is not None:
+ outputstore.addunit(outputunit)
+ outputstore.removeduplicates(duplicatestyle)
+ return outputstore
+
+ def mergestore(self, templatestore, inputstore, blankmsgstr=False, duplicatestyle="msgctxt"):
+ """converts two .properties files to a .po file..."""
+ outputstore = po.pofile()
+ outputheader = outputstore.makeheader(charset="UTF-8", encoding="8bit")
+ outputheader.addnote("extracted from %s, %s" % (templatestore.filename, inputstore.filename), "developer")
+ outputstore.addunit(outputheader)
+ inputstore.makeindex()
+ # loop through the original file, looking at units one by one
+ for templateunit in templatestore.units:
+ outputunit = self.convertunit(templateunit, "developer")
+ # try and find a translation of the same name...
+ if templateunit.name in inputstore.locationindex:
+ translatedinputunit = inputstore.locationindex[templateunit.name]
+ # Need to check that this comment is not a copy of the developer comments
+ translatedoutputunit = self.convertunit(translatedinputunit, "translator")
+ else:
+ translatedoutputunit = None
+ # if we have a valid po unit, get the translation and add it...
+ if outputunit is not None:
+ if translatedoutputunit is not None and not blankmsgstr:
+ outputunit.target = translatedoutputunit.source
+ outputstore.addunit(outputunit)
+ elif translatedoutputunit is not None:
+ print >> sys.stderr, "error converting original properties definition %s" % templateunit.name
+ outputstore.removeduplicates(duplicatestyle)
+ return outputstore
+
+ def convertunit(self, inputunit, origin):
+ """Converts a .php unit to a .po unit"""
+ outputunit = po.pounit(encoding="UTF-8")
+ outputunit.addnote(inputunit.getnotes(origin), origin)
+ outputunit.addlocation("".join(inputunit.getlocations()))
+ outputunit.source = inputunit.source
+ outputunit.target = ""
+ return outputunit
+
+def convertphp(inputfile, outputfile, templatefile, pot=False, duplicatestyle="msgctxt"):
+ """reads in inputfile using php, converts using php2po, writes to outputfile"""
+ inputstore = php.phpfile(inputfile)
+ convertor = php2po()
+ if templatefile is None:
+ outputstore = convertor.convertstore(inputstore, duplicatestyle=duplicatestyle)
+ else:
+ templatestore = php.phpfile(templatefile)
+ outputstore = convertor.mergestore(templatestore, inputstore, blankmsgstr=pot, duplicatestyle=duplicatestyle)
+ if outputstore.isempty():
+ return 0
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"php": ("po", convertphp), ("php", "php"): ("po", convertphp)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__)
+ parser.add_duplicates_option()
+ parser.passthrough.append("pot")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2csv b/translate-toolkit-1.5.1/translate/convert/po2csv
new file mode 100755
index 0000000..53a6828
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2csv
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2003, 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a gettext .po localization file to a comma-separated values (.csv) file"""
+
+from translate.convert import po2csv
+
+if __name__ == '__main__':
+ po2csv.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2csv.py b/translate-toolkit-1.5.1/translate/convert/po2csv.py
new file mode 100644
index 0000000..740dc04
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2csv.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2003-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""convert Gettext PO localization files to Comma-Separated Value (.csv) files
+
+see: http://translate.sourceforge.net/wiki/toolkit/po2csv for examples and
+usage instructions
+"""
+
+from translate.storage import po
+from translate.storage import csvl10n
+
+class po2csv:
+ def convertcomments(self, inputunit):
+ return " ".join(inputunit.getlocations())
+
+ def convertunit(self, inputunit):
+ csvunit = csvl10n.csvunit()
+ if inputunit.isheader():
+ csvunit.comment = "location"
+ csvunit.source = "source"
+ csvunit.target = "target"
+ elif inputunit.isblank():
+ return None
+ else:
+ csvunit.comment = self.convertcomments(inputunit)
+ csvunit.source = inputunit.source
+ csvunit.target = inputunit.target
+ return csvunit
+
+ def convertplurals(self, inputunit):
+ csvunit = csvl10n.csvunit()
+ csvunit.comment = self.convertcomments(inputunit)
+ csvunit.source = inputunit.source.strings[1]
+ csvunit.target = inputunit.target.strings[1]
+ return csvunit
+
+ def convertstore(self, inputstore, columnorder=None):
+ outputstore = csvl10n.csvfile(fieldnames=columnorder)
+ for inputunit in inputstore.units:
+ outputunit = self.convertunit(inputunit)
+ if outputunit is not None:
+ outputstore.addunit(outputunit)
+ if inputunit.hasplural():
+ outputunit = self.convertplurals(inputunit)
+ if outputunit is not None:
+ outputstore.addunit(outputunit)
+ return outputstore
+
+def convertcsv(inputfile, outputfile, templatefile, columnorder=None):
+ """reads in inputfile using po, converts using po2csv, writes to outputfile"""
+ # note that templatefile is not used, but it is required by the converter...
+ inputstore = po.pofile(inputfile)
+ if inputstore.isempty():
+ return 0
+ convertor = po2csv()
+ outputstore = convertor.convertstore(inputstore, columnorder)
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"po":("csv", convertcsv)}
+ parser = convert.ConvertOptionParser(formats, usepots=True, description=__doc__)
+ parser.add_option("", "--columnorder", dest="columnorder", default=None,
+ help="specify the order and position of columns (location,source,target)")
+ parser.passthrough.append("columnorder")
+ parser.run(argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2dtd.py b/translate-toolkit-1.5.1/translate/convert/po2dtd.py
new file mode 100644
index 0000000..c068f20
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2dtd.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2009 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""script that converts a .po file to a UTF-8 encoded .dtd file as used by mozilla
+either done using a template or just using the .po file"""
+
+from translate.storage import dtd
+from translate.storage import po
+from translate.misc import quote
+from translate.convert import accesskey
+import warnings
+
+def getmixedentities(entities):
+ """returns a list of mixed .label and .accesskey entities from a list of entities"""
+ mixedentities = [] # those entities which have a .label and .accesskey combined
+ # search for mixed entities...
+ for entity in entities:
+ for labelsuffix in dtd.labelsuffixes:
+ if entity.endswith(labelsuffix):
+ entitybase = entity[:entity.rfind(labelsuffix)]
+ # see if there is a matching accesskey, making this a mixed entity
+ for akeytype in dtd.accesskeysuffixes:
+ if entitybase + akeytype in entities:
+ # add both versions to the list of mixed entities
+ mixedentities += [entity, entitybase+akeytype]
+ return mixedentities
+
+def applytranslation(entity, dtdunit, inputunit, mixedentities):
+ """applies the translation for entity in the po unit to the dtd unit"""
+ # this converts the po-style string to a dtd-style string
+ unquotedstr = inputunit.target
+ # check there aren't missing entities...
+ if len(unquotedstr.strip()) == 0:
+ return
+ # handle mixed entities
+ for labelsuffix in dtd.labelsuffixes:
+ if entity.endswith(labelsuffix):
+ if entity in mixedentities:
+ unquotedstr, akey = accesskey.extract(unquotedstr)
+ break
+ else:
+ for akeytype in dtd.accesskeysuffixes:
+ if entity.endswith(akeytype):
+ if entity in mixedentities:
+ label, unquotedstr = accesskey.extract(unquotedstr)
+ if not unquotedstr:
+ warnings.warn("Could not find accesskey for %s" % entity)
+ else:
+ original = dtd.unquotefromdtd(dtdunit.definition)
+ # For the sake of diffs we keep the case of the
+ # accesskey the same if we know the translation didn't
+ # change. Casing matters in XUL.
+ if unquotedstr == dtdunit.source and original.lower() == unquotedstr.lower():
+ if original.isupper():
+ unquotedstr = unquotedstr.upper()
+ elif original.islower():
+ unquotedstr = unquotedstr.lower()
+ if len(unquotedstr) > 0:
+ dtdunit.definition = dtd.quotefordtd(dtd.removeinvalidamps(entity, unquotedstr))
+
+class redtd:
+ """this is a convertor class that creates a new dtd based on a template using translations in a po"""
+ def __init__(self, dtdfile):
+ self.dtdfile = dtdfile
+
+ def convertstore(self, inputstore, includefuzzy=False):
+ # translate the strings
+ for inunit in inputstore.units:
+ # there may be more than one entity due to msguniq merge
+ if includefuzzy or not inunit.isfuzzy():
+ self.handleinunit(inunit)
+ return self.dtdfile
+
+ def handleinunit(self, inunit):
+ entities = inunit.getlocations()
+ mixedentities = getmixedentities(entities)
+ for entity in entities:
+ if self.dtdfile.index.has_key(entity):
+ # now we need to replace the definition of entity with msgstr
+ dtdunit = self.dtdfile.index[entity] # find the dtd
+ applytranslation(entity, dtdunit, inunit, mixedentities)
+
+class po2dtd:
+ """this is a convertor class that creates a new dtd file based on a po file without a template"""
+ def convertcomments(self, inputunit, dtdunit):
+ entities = inputunit.getlocations()
+ if len(entities) > 1:
+ # don't yet handle multiple entities
+ dtdunit.comments.append(("conversionnote",'<!-- CONVERSION NOTE - multiple entities -->\n'))
+ dtdunit.entity = entities[0]
+ elif len(entities) == 1:
+ dtdunit.entity = entities[0]
+ else:
+ # this produces a blank entity, which doesn't write anything out
+ dtdunit.entity = ""
+
+ if inputunit.isfuzzy():
+ dtdunit.comments.append(("potype", "fuzzy\n"))
+ for note in inputunit.getnotes("translator").split("\n"):
+ if not note:
+ continue
+ note = quote.unstripcomment(note)
+ if (note.find('LOCALIZATION NOTE') == -1) or (note.find('GROUP') == -1):
+ dtdunit.comments.append(("comment", note))
+ # msgidcomments are special - they're actually localization notes
+ msgidcomment = inputunit._extract_msgidcomments()
+ if msgidcomment:
+ locnote = quote.unstripcomment("LOCALIZATION NOTE ("+dtdunit.entity+"): "+msgidcomment)
+ dtdunit.comments.append(("locnote", locnote))
+
+
+ def convertstrings(self, inputunit, dtdunit):
+ if inputunit.istranslated():
+ unquoted = inputunit.target
+ else:
+ unquoted = inputunit.source
+ dtdunit.definition = dtd.quotefordtd(dtd.removeinvalidamps(dtdunit.entity, unquoted))
+
+ def convertunit(self, inputunit):
+ dtdunit = dtd.dtdunit()
+ self.convertcomments(inputunit, dtdunit)
+ self.convertstrings(inputunit, dtdunit)
+ return dtdunit
+
+ def convertstore(self, inputstore, includefuzzy=False):
+ outputstore = dtd.dtdfile()
+ self.currentgroups = []
+ for inputunit in inputstore.units:
+ if includefuzzy or not inputunit.isfuzzy():
+ dtdunit = self.convertunit(inputunit)
+ if dtdunit is not None:
+ outputstore.addunit(dtdunit)
+ return outputstore
+
+def convertdtd(inputfile, outputfile, templatefile, includefuzzy=False):
+ inputstore = po.pofile(inputfile)
+ if templatefile is None:
+ convertor = po2dtd()
+ else:
+ templatestore = dtd.dtdfile(templatefile)
+ convertor = redtd(templatestore)
+ outputstore = convertor.convertstore(inputstore, includefuzzy)
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ # handle command line options
+ from translate.convert import convert
+ formats = {"po": ("dtd", convertdtd), ("po", "dtd"): ("dtd", convertdtd)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ parser.add_fuzzy_option()
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2html b/translate-toolkit-1.5.1/translate/convert/po2html
new file mode 100755
index 0000000..37c02d7
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2html
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""translates html files using gettext .po localization
+You can generate the po files using html2po"""
+
+from translate.convert import po2html
+
+if __name__ == '__main__':
+ po2html.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2html.py b/translate-toolkit-1.5.1/translate/convert/po2html.py
new file mode 100644
index 0000000..eed2780
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2html.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert Gettext PO localization files to HTML files
+
+see: http://translate.sourceforge.net/wiki/toolkit/po2html for examples and
+usage instructions
+"""
+
+from translate.storage import po
+try:
+ import textwrap
+except:
+ textwrap = None
+
+try:
+ import tidy
+except:
+ tidy = None
+
+class po2html:
+ """po2html can take a po file and generate html. best to give it a template file otherwise will just concat msgstrs"""
+ def __init__(self, wrap=None, usetidy=None):
+ self.wrap = wrap
+ self.tidy = tidy and usetidy
+
+ def wrapmessage(self, message):
+ """rewraps text as required"""
+ if self.wrap is None:
+ return message
+ return "\n".join([textwrap.fill(line, self.wrap, replace_whitespace=False) for line in message.split("\n")])
+
+ def convertstore(self, inputstore, includefuzzy):
+ """converts a file to .po format"""
+ htmlresult = ""
+ for inputunit in inputstore.units:
+ if inputunit.isheader():
+ continue
+ if includefuzzy or not inputunit.isfuzzy():
+ htmlresult += self.wrapmessage(inputunit.target) + "\n" + "\n"
+ else:
+ htmlresult += self.wrapmessage(inputunit.source) + "\n" + "\n"
+ return htmlresult.encode('utf-8')
+
+ def mergestore(self, inputstore, templatetext, includefuzzy):
+ """converts a file to .po format"""
+ htmlresult = templatetext.replace("\n", " ")
+ if isinstance(htmlresult, str):
+ #TODO: get the correct encoding
+ htmlresult = htmlresult.decode('utf-8')
+ # TODO: use the algorithm from html2po to get blocks and translate them individually
+ # rather than using replace
+ for inputunit in inputstore.units:
+ if inputunit.isheader():
+ continue
+ msgid = inputunit.source
+ msgstr = None
+ if includefuzzy or not inputunit.isfuzzy():
+ msgstr = self.wrapmessage(inputunit.target)
+ else:
+ msgstr = self.wrapmessage(inputunit.source)
+ if msgstr.strip():
+ # TODO: "msgid" is already html-encoded ("&" -> "&amp;"), while
+ # "msgstr" is not encoded -> thus the replace fails
+ # see test_po2html.py in line 67
+ htmlresult = htmlresult.replace(msgid, msgstr, 1)
+ htmlresult = htmlresult.encode('utf-8')
+ if self.tidy:
+ htmlresult = str(tidy.parseString(htmlresult))
+ return htmlresult
+
+def converthtml(inputfile, outputfile, templatefile, wrap=None, includefuzzy=False, usetidy=True):
+ """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout"""
+ inputstore = po.pofile(inputfile)
+ convertor = po2html(wrap=wrap, usetidy=usetidy)
+ if templatefile is None:
+ outputstring = convertor.convertstore(inputstore, includefuzzy)
+ else:
+ templatestring = templatefile.read()
+ outputstring = convertor.mergestore(inputstore, templatestring, includefuzzy)
+ outputfilepos = outputfile.tell()
+ outputfile.write(outputstring)
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ from translate.misc import stdiotell
+ import sys
+ sys.stdout = stdiotell.StdIOWrapper(sys.stdout)
+ formats = {("po", "htm"):("htm", converthtml), ("po", "html"):("html", converthtml), ("po", "xhtml"):("xhtml", converthtml), ("po"):("html", converthtml)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ if textwrap is not None:
+ parser.add_option("-w", "--wrap", dest="wrap", default=None, type="int",
+ help="set number of columns to wrap html at", metavar="WRAP")
+ parser.passthrough.append("wrap")
+ if tidy is not None:
+ parser.add_option("", "--notidy", dest="usetidy", default=True,
+ help="disables the use of HTML tidy", action="store_false")
+ parser.passthrough.append("usetidy")
+ parser.add_fuzzy_option()
+ parser.run(argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2ical b/translate-toolkit-1.5.1/translate/convert/po2ical
new file mode 100755
index 0000000..13a34eb
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2ical
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a gettext .po localization file to an iCal file"""
+
+from translate.convert import po2ical
+
+if __name__ == '__main__':
+ po2ical.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2ical.py b/translate-toolkit-1.5.1/translate/convert/po2ical.py
new file mode 100644
index 0000000..b914afc
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2ical.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+"""convert Gettext PO localization files to iCal files"""
+
+from translate.storage import factory
+from translate.storage import ical
+
+class reical:
+ def __init__(self, templatefile):
+ self.templatefile = templatefile
+ self.templatestore = ical.icalfile(templatefile)
+ self.inputdict = {}
+
+ def convertstore(self, inputstore, includefuzzy=False):
+ self.makestoredict(inputstore, includefuzzy)
+ for unit in self.templatestore.units:
+ for location in unit.getlocations():
+ if self.inputdict.has_key(location):
+ unit.target = self.inputdict[location]
+ else:
+ unit.target = unit.source
+ return str(self.templatestore)
+
+ def makestoredict(self, store, includefuzzy=False):
+ # make a dictionary of the translations
+ for unit in store.units:
+ if includefuzzy or not unit.isfuzzy():
+ # there may be more than one entity due to msguniq merge
+ for location in unit.getlocations():
+ inistring = unit.target
+ if len(inistring.strip()) == 0:
+ inistring = unit.source
+ self.inputdict[location] = inistring
+
+def convertical(inputfile, outputfile, templatefile, includefuzzy=False):
+ inputstore = factory.getobject(inputfile)
+ if templatefile is None:
+ raise ValueError("must have template file for iCal files")
+ else:
+ convertor = reical(templatefile)
+ outputstring = convertor.convertstore(inputstore, includefuzzy)
+ outputfile.write(outputstring)
+ return 1
+
+def main(argv=None):
+ # handle command line options
+ from translate.convert import convert
+ formats = {("po", "ics"): ("ics", convertical)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ parser.add_fuzzy_option()
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2ini b/translate-toolkit-1.5.1/translate/convert/po2ini
new file mode 100755
index 0000000..8abff3c
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2ini
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a gettext .po localization file to a .ini file"""
+
+from translate.convert import po2ini
+
+if __name__ == '__main__':
+ po2ini.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2ini.py b/translate-toolkit-1.5.1/translate/convert/po2ini.py
new file mode 100644
index 0000000..b0f12ea
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2ini.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+"""convert Gettext PO localization files to .ini files"""
+
+from translate.storage import factory
+from translate.storage import ini
+
+class reini:
+ def __init__(self, templatefile, dialect):
+ self.templatefile = templatefile
+ self.templatestore = ini.inifile(templatefile, dialect=dialect)
+ self.inputdict = {}
+
+ def convertstore(self, inputstore, includefuzzy=False):
+ self.makestoredict(inputstore, includefuzzy)
+ for unit in self.templatestore.units:
+ for location in unit.getlocations():
+ unit.target = self.inputdict[location]
+ return str(self.templatestore)
+
+ def makestoredict(self, store, includefuzzy=False):
+ # make a dictionary of the translations
+ for unit in store.units:
+ if includefuzzy or not unit.isfuzzy():
+ # there may be more than one entity due to msguniq merge
+ for location in unit.getlocations():
+ inistring = unit.target
+ if len(inistring.strip()) == 0:
+ inistring = unit.source
+ self.inputdict[location] = inistring
+
+def convertini(inputfile, outputfile, templatefile, includefuzzy=False, dialect="default"):
+ inputstore = factory.getobject(inputfile)
+ if templatefile is None:
+ raise ValueError("must have template file for ini files")
+ else:
+ convertor = reini(templatefile, dialect)
+ outputstring = convertor.convertstore(inputstore, includefuzzy)
+ outputfile.write(outputstring)
+ return 1
+
+def convertisl(inputfile, outputfile, templatefile, includefuzzy=False, dialect="inno"):
+ convertini(inputfile, outputfile, templatefile, includefuzzy=False, dialect=dialect)
+
+def main(argv=None):
+ # handle command line options
+ from translate.convert import convert
+ formats = {
+ ("po", "ini"): ("ini", convertini),
+ ("po", "isl"): ("isl", convertisl),
+ }
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ parser.add_fuzzy_option()
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2moz b/translate-toolkit-1.5.1/translate/convert/po2moz
new file mode 100755
index 0000000..de39a93
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2moz
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""script that converts a set of .po files to a set of .dtd and .properties files
+either done using a template or just using the .po file"""
+
+from translate.convert import po2moz
+
+if __name__ == '__main__':
+ po2moz.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2moz.py b/translate-toolkit-1.5.1/translate/convert/po2moz.py
new file mode 100644
index 0000000..64c798b
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2moz.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""convert Gettext PO localization files to Mozilla .dtd and .properties files
+
+see: http://translate.sourceforge.net/wiki/toolkit/po2moz for examples and
+usage instructions
+"""
+
+import os.path
+from translate.convert import po2dtd
+from translate.convert import po2prop
+from translate.convert import prop2mozfunny
+from translate.storage import xpi
+from translate.convert import convert
+
+class MozConvertOptionParser(convert.ArchiveConvertOptionParser):
+ def __init__(self, formats, usetemplates=False, usepots=False, description=None):
+ convert.ArchiveConvertOptionParser.__init__(self, formats, usetemplates, usepots, description=description, archiveformats={"xpi": xpi.XpiFile})
+
+ def initoutputarchive(self, options):
+ """creates an outputarchive if required"""
+ if options.output and self.isarchive(options.output, 'output'):
+ newlang = None
+ newregion = None
+ if options.locale is not None:
+ if options.locale.count("-") > 1:
+ raise ValueError("Invalid locale: %s - should be of the form xx-YY" % options.locale)
+ elif "-" in options.locale:
+ newlang, newregion = options.locale.split("-")
+ else:
+ newlang, newregion = options.locale, ""
+ if options.clonexpi is not None:
+ originalxpi = xpi.XpiFile(options.clonexpi, "r")
+ options.outputarchive = originalxpi.clone(options.output, "w", newlang=newlang, newregion=newregion)
+ elif self.isarchive(options.template, 'template'):
+ options.outputarchive = options.templatearchive.clone(options.output, "a", newlang=newlang, newregion=newregion)
+ else:
+ if os.path.exists(options.output):
+ options.outputarchive = xpi.XpiFile(options.output, "a", locale=newlang, region=newregion)
+ else:
+ # FIXME: this is unlikely to work because it has no jar files
+ options.outputarchive = xpi.XpiFile(options.output, "w", locale=newlang, region=newregion)
+
+ def splitinputext(self, inputpath):
+ """splits a inputpath into name and extension"""
+ # TODO: not sure if this should be here, was in po2moz
+ d, n = os.path.dirname(inputpath), os.path.basename(inputpath)
+ s = n.find(".")
+ if s == -1:
+ return (inputpath, "")
+ root = os.path.join(d, n[:s])
+ ext = n[s+1:]
+ return (root, ext)
+
+ def recursiveprocess(self, options):
+ """recurse through directories and convert files"""
+ self.replacer.replacestring = options.locale
+ result = super(MozConvertOptionParser, self).recursiveprocess(options)
+ if self.isarchive(options.output, 'output'):
+ if options.progress in ('console', 'verbose'):
+ print "writing xpi file..."
+ options.outputarchive.close()
+ return result
+
+def main(argv=None):
+ # handle command line options
+ formats = {("dtd.po", "dtd"): ("dtd", po2dtd.convertdtd),
+ ("properties.po", "properties"): ("properties", po2prop.convertmozillaprop),
+ ("it.po", "it"): ("it", prop2mozfunny.po2it),
+ ("ini.po", "ini"): ("ini", prop2mozfunny.po2ini),
+ ("inc.po", "inc"): ("inc", prop2mozfunny.po2inc),
+ # (None, "*"): ("*", convert.copytemplate),
+ ("*", "*"): ("*", convert.copyinput),
+ "*": ("*", convert.copyinput)}
+ # handle search and replace
+ replacer = convert.Replacer("${locale}", None)
+ for replaceformat in ("js", "rdf", "manifest"):
+ formats[(None, replaceformat)] = (replaceformat, replacer.searchreplacetemplate)
+ formats[(replaceformat, replaceformat)] = (replaceformat, replacer.searchreplaceinput)
+ formats[replaceformat] = (replaceformat, replacer.searchreplaceinput)
+ parser = MozConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ parser.add_option("-l", "--locale", dest="locale", default=None,
+ help="set output locale (required as this sets the directory names)", metavar="LOCALE")
+ parser.add_option("", "--clonexpi", dest="clonexpi", default=None,
+ help="clone xpi structure from the given xpi file")
+ parser.add_fuzzy_option()
+ parser.replacer = replacer
+ parser.run(argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2oo b/translate-toolkit-1.5.1/translate/convert/po2oo
new file mode 100755
index 0000000..e7e41d9
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2oo
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+#
+# Copyright 2002-2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""script that converts a .po file with translations based on a .pot file
+generated from a OpenOffice localization .oo back to the .oo (but translated)
+Uses the original .oo to do the conversion as this makes sure we don't
+leave out any unincluded stuff..."""
+
+from translate.convert import po2oo
+
+if __name__ == '__main__':
+ po2oo.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2oo.py b/translate-toolkit-1.5.1/translate/convert/po2oo.py
new file mode 100644
index 0000000..f3e1537
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2oo.py
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert Gettext PO localization files to an OpenOffice.org (SDF) localization file
+
+see: http://translate.sourceforge.net/wiki/toolkit/po2oo for examples and
+usage instructions
+"""
+
+import sys
+import os
+from translate.storage import oo
+from translate.storage import factory
+from translate.filters import pofilter
+from translate.filters import checks
+from translate.filters import autocorrect
+import time
+
+class reoo:
+ def __init__(self, templatefile, languages=None, timestamp=None, includefuzzy=False, long_keys=False, filteraction="exclude"):
+ """construct a reoo converter for the specified languages (timestamp=0 means leave unchanged)"""
+ # languages is a pair of language ids
+ self.long_keys = long_keys
+ self.readoo(templatefile)
+ self.languages = languages
+ self.filteraction = filteraction
+ if timestamp is None:
+ self.timestamp = time.strptime("2002-02-02 02:02:02", "%Y-%m-%d %H:%M:%S")
+ else:
+ self.timestamp = timestamp
+ if self.timestamp:
+ self.timestamp_str = time.strftime("%Y-%m-%d %H:%M:%S", self.timestamp)
+ else:
+ self.timestamp_str = None
+ self.includefuzzy = includefuzzy
+
+ def makeindex(self):
+ """makes an index of the oo keys that are used in the source file"""
+ self.index = {}
+ for ookey, theoo in self.o.ookeys.iteritems():
+ sourcekey = oo.makekey(ookey, self.long_keys)
+ self.index[sourcekey] = theoo
+
+ def readoo(self, of):
+ """read in the oo from the file"""
+ oosrc = of.read()
+ self.o = oo.oofile()
+ self.o.parse(oosrc)
+ self.makeindex()
+
+ def handleunit(self, unit):
+ # TODO: make this work for multiple columns in oo...
+ locations = unit.getlocations()
+ # technically our formats should just have one location for each entry...
+ # but we handle multiple ones just to be safe...
+ for location in locations:
+ subkeypos = location.rfind('.')
+ subkey = location[subkeypos+1:]
+ key = location[:subkeypos]
+ # this is just to handle our old system of using %s/%s:%s instead of %s/%s#%s
+ key = key.replace(':', '#')
+ # this is to handle using / instead of \ in the sourcefile...
+ key = key.replace('\\', '/')
+ key = oo.normalizefilename(key)
+ if self.index.has_key(key):
+ # now we need to replace the definition of entity with msgstr
+ theoo = self.index[key] # find the oo
+ self.applytranslation(key, subkey, theoo, unit)
+ else:
+ print >> sys.stderr, "couldn't find key %s from po in %d keys" % (key, len(self.index))
+ try:
+ sourceunitlines = str(unit)
+ if isinstance(sourceunitlines, unicode):
+ sourceunitlines = sourceunitlines.encode("utf-8")
+ print >> sys.stderr, sourceunitlines
+ except:
+ print >> sys.stderr, "error outputting source unit %r" % (str(unit),)
+
+ def applytranslation(self, key, subkey, theoo, unit):
+ """applies the translation from the source unit to the oo unit"""
+ if not self.includefuzzy and unit.isfuzzy():
+ return
+ makecopy = False
+ if self.languages is None:
+ part1 = theoo.lines[0]
+ if len(theoo.lines) > 1:
+ part2 = theoo.lines[1]
+ else:
+ makecopy = True
+ else:
+ part1 = theoo.languages[self.languages[0]]
+ if self.languages[1] in theoo.languages:
+ part2 = theoo.languages[self.languages[1]]
+ else:
+ makecopy = True
+ if makecopy:
+ part2 = oo.ooline(part1.getparts())
+ unquotedid = unit.source
+ unquotedstr = unit.target
+ # If there is no translation, we don't want to add a line
+ if len(unquotedstr) == 0:
+ return
+ if isinstance(unquotedstr, unicode):
+ unquotedstr = unquotedstr.encode("UTF-8")
+ # finally set the new definition in the oo, but not if its empty
+ if len(unquotedstr) > 0:
+ setattr(part2, subkey, unquotedstr)
+ # set the modified time
+ if self.timestamp_str:
+ part2.timestamp = self.timestamp_str
+ if self.languages:
+ part2.languageid = self.languages[1]
+ if makecopy:
+ theoo.addline(part2)
+
+ def convertstore(self, sourcestore):
+ self.p = sourcestore
+ # translate the strings
+ for unit in self.p.units:
+ # there may be more than one element due to msguniq merge
+ if filter.validelement(unit, self.p.filename, self.filteraction):
+ self.handleunit(unit)
+ # return the modified oo file object
+ return self.o
+
+def getmtime(filename):
+ import stat
+ return time.localtime(os.stat(filename)[stat.ST_MTIME])
+
+class oocheckfilter(pofilter.pocheckfilter):
+ def validelement(self, unit, filename, filteraction):
+ """Returns whether or not to use unit in conversion. (filename is just for error reporting)"""
+ if filteraction == "none": return True
+ filterresult = self.filterunit(unit)
+ if filterresult:
+ if filterresult != autocorrect:
+ for filtername, filtermessage in filterresult.iteritems():
+ location = unit.getlocations()[0].encode('utf-8')
+ if filtername in self.options.error:
+ print >> sys.stderr, "Error at %s::%s: %s" % (filename, location, filtermessage)
+ return not filteraction in ["exclude-all", "exclude-serious"]
+ if filtername in self.options.warning or self.options.alwayswarn:
+ print >> sys.stderr, "Warning at %s::%s: %s" % (filename, location, filtermessage)
+ return not filteraction in ["exclude-all"]
+ return True
+
+class oofilteroptions:
+ error = ['variables', 'xmltags', 'escapes']
+ warning = ['blank']
+ #To only issue warnings for tests listed in warning, change the following to False:
+ alwayswarn = True
+ limitfilters = error + warning
+ #To use all available tests, uncomment the following:
+ #limitfilters = []
+ #To exclude certain tests, list them in here:
+ excludefilters = {}
+ includefuzzy = False
+ includereview = False
+ includeheader = False
+ autocorrect = False
+
+options = oofilteroptions()
+filter = oocheckfilter(options, [checks.OpenOfficeChecker, checks.StandardUnitChecker], checks.openofficeconfig)
+
+def convertoo(inputfile, outputfile, templatefile, sourcelanguage=None, targetlanguage=None, timestamp=None, includefuzzy=False, multifilestyle="single", filteraction=None):
+ inputstore = factory.getobject(inputfile)
+ inputstore.filename = getattr(inputfile, 'name', '')
+ if not targetlanguage:
+ raise ValueError("You must specify the target language")
+ if not sourcelanguage:
+ if targetlanguage.isdigit():
+ sourcelanguage = "01"
+ else:
+ sourcelanguage = "en-US"
+ languages = (sourcelanguage, targetlanguage)
+ if templatefile is None:
+ raise ValueError("must have template file for oo files")
+ else:
+ convertor = reoo(templatefile, languages=languages, timestamp=timestamp, includefuzzy=includefuzzy, long_keys=multifilestyle != "single", filteraction=filteraction)
+ outputstore = convertor.convertstore(inputstore)
+ # TODO: check if we need to manually delete missing items
+ outputfile.write(str(outputstore))
+ return True
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {("po", "oo"):("oo", convertoo), ("xlf", "oo"):("oo", convertoo), ("po", "sdf"):("sdf", convertoo)}
+ # always treat the input as an archive unless it is a directory
+ archiveformats = {(None, "output"): oo.oomultifile, (None, "template"): oo.oomultifile}
+ parser = convert.ArchiveConvertOptionParser(formats, usetemplates=True, description=__doc__, archiveformats=archiveformats)
+ parser.add_option("-l", "--language", dest="targetlanguage", default=None,
+ help="set target language code (e.g. af-ZA) [required]", metavar="LANG")
+ parser.add_option("", "--source-language", dest="sourcelanguage", default=None,
+ help="set source language code (default en-US)", metavar="LANG")
+ parser.add_option("-T", "--keeptimestamp", dest="timestamp", default=None, action="store_const", const=0,
+ help="don't change the timestamps of the strings")
+ parser.add_option("", "--nonrecursiveoutput", dest="allowrecursiveoutput", default=True, action="store_false", help="don't treat the output oo as a recursive store")
+ parser.add_option("", "--nonrecursivetemplate", dest="allowrecursivetemplate", default=True, action="store_false", help="don't treat the template oo as a recursive store")
+ parser.add_option("", "--filteraction", dest="filteraction", default="none", metavar="ACTION",
+ help="action on pofilter failure: none (default), warn, exclude-serious, exclude-all")
+ parser.add_fuzzy_option()
+ parser.add_multifile_option()
+ parser.passthrough.append("sourcelanguage")
+ parser.passthrough.append("targetlanguage")
+ parser.passthrough.append("timestamp")
+ parser.passthrough.append("filteraction")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2php b/translate-toolkit-1.5.1/translate/convert/po2php
new file mode 100755
index 0000000..013e1c3
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2php
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""translates php files using gettext .po localization
+You can generate the po files using php2po"""
+
+from translate.convert import po2php
+
+if __name__ == '__main__':
+ po2php.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2php.py b/translate-toolkit-1.5.1/translate/convert/po2php.py
new file mode 100644
index 0000000..cc59ec8
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2php.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2008 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+"""convert Gettext PO localization files to PHP localization files
+
+see: http://translate.sourceforge.net/wiki/toolkit/po2php for examples and
+usage instructions
+"""
+
+from translate.misc import quote
+from translate.storage import po
+from translate.storage import php
+
+eol = "\n"
+
+class rephp:
+ def __init__(self, templatefile):
+ self.templatefile = templatefile
+ self.inputdict = {}
+
+ def convertstore(self, inputstore, includefuzzy=False):
+ self.inmultilinemsgid = False
+ self.inecho = False
+ self.makestoredict(inputstore, includefuzzy)
+ outputlines = []
+ for line in self.templatefile.readlines():
+ outputstr = self.convertline(line)
+ outputlines.append(outputstr)
+ return outputlines
+
+ def makestoredict(self, store, includefuzzy=False):
+ '''make a dictionary of the translations'''
+ for unit in store.units:
+ if includefuzzy or not unit.isfuzzy():
+ for location in unit.getlocations():
+ inputstring = unit.target
+ if len(inputstring.strip()) == 0:
+ inputstring = unit.source
+ self.inputdict[location] = inputstring
+
+ def convertline(self, line):
+ line = unicode(line, 'utf-8')
+ returnline = ""
+ # handle multiline msgid if we're in one
+ if self.inmultilinemsgid:
+ # see if there's more
+ endpos = line.rfind("%s;" % self.quotechar)
+ # if there was no '; or the quote is escaped, we have to continue
+ if endpos >= 0 and line[endpos-1] != '\\':
+ self.inmultilinemsgid = False
+ # if we're echoing...
+ if self.inecho:
+ returnline = line
+ # otherwise, this could be a comment
+ elif line.strip()[:2] == '//' or line.strip()[:2] == '/*':
+ returnline = quote.rstripeol(line)+eol
+ else:
+ line = quote.rstripeol(line)
+ equalspos = line.find('=')
+ # if no equals, just repeat it
+ if equalspos == -1:
+ returnline = quote.rstripeol(line)+eol
+ # otherwise, this is a definition
+ else:
+ # now deal with the current string...
+ key = line[:equalspos].strip()
+ lookupkey = key.replace(" ", "")
+ # Calculate space around the equal sign
+ prespace = line[len(line[:equalspos].rstrip()):equalspos]
+ postspacestart = len(line[equalspos+1:])
+ postspaceend = len(line[equalspos+1:].lstrip())
+ postspace = line[equalspos+1:equalspos+(postspacestart-postspaceend)+1]
+ self.quotechar = line[equalspos+(postspacestart-postspaceend)+1]
+ inlinecomment = line[line.rfind("%s;" % self.quotechar)+2:]
+ if self.inputdict.has_key(lookupkey):
+ self.inecho = False
+ value = php.phpencode(self.inputdict[lookupkey], self.quotechar)
+ if isinstance(value, str):
+ value = value.decode('utf8')
+ returnline = key + prespace + "=" + postspace + self.quotechar + value + self.quotechar + ';' + inlinecomment + eol
+ else:
+ self.inecho = True
+ returnline = line+eol
+ # no string termination means carry string on to next line
+ endpos = line.rfind("%s;" % self.quotechar)
+ # if there was no '; or the quote is escaped, we have to continue
+ if endpos == -1 or line[endpos-1] == '\\':
+ self.inmultilinemsgid = True
+ if isinstance(returnline, unicode):
+ returnline = returnline.encode('utf-8')
+ return returnline
+
+def convertphp(inputfile, outputfile, templatefile, includefuzzy=False):
+ inputstore = po.pofile(inputfile)
+ if templatefile is None:
+ raise ValueError("must have template file for php files")
+ # convertor = po2php()
+ else:
+ convertor = rephp(templatefile)
+ outputphplines = convertor.convertstore(inputstore, includefuzzy)
+ outputfile.writelines(outputphplines)
+ return 1
+
+def main(argv=None):
+ # handle command line options
+ from translate.convert import convert
+ formats = {("po", "php"): ("php", convertphp)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ parser.add_fuzzy_option()
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2prop b/translate-toolkit-1.5.1/translate/convert/po2prop
new file mode 100755
index 0000000..b551c6e
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2prop
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2002, 2003 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a gettext .po localization file to a .properties file"""
+
+from translate.convert import po2prop
+
+if __name__ == '__main__':
+ po2prop.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2prop.py b/translate-toolkit-1.5.1/translate/convert/po2prop.py
new file mode 100644
index 0000000..0fafe8a
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2prop.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+"""convert Gettext PO localization files to Java/Mozilla .properties files
+
+see: http://translate.sourceforge.net/wiki/toolkit/po2prop for examples and
+usage instructions
+"""
+
+from translate.misc import quote
+from translate.storage import po
+
+eol = "\n"
+
+class reprop:
+ def __init__(self, templatefile):
+ self.templatefile = templatefile
+ self.inputdict = {}
+
+ def convertstore(self, inputstore, personality, includefuzzy=False):
+ self.personality = personality
+ self.inmultilinemsgid = False
+ self.inecho = False
+ self.makestoredict(inputstore, includefuzzy)
+ outputlines = []
+ for line in self.templatefile.readlines():
+ outputstr = self.convertline(line)
+ outputlines.append(outputstr)
+ return outputlines
+
+ def makestoredict(self, store, includefuzzy=False):
+ # make a dictionary of the translations
+ for unit in store.units:
+ if includefuzzy or not unit.isfuzzy():
+ # there may be more than one entity due to msguniq merge
+ for entity in unit.getlocations():
+ propstring = unit.target
+
+ # NOTE: triple-space as a string means leave it empty (special signal)
+ if len(propstring.strip()) == 0 and propstring != " ":
+ propstring = unit.source
+ self.inputdict[entity] = propstring
+
+ def convertline(self, line):
+ returnline = ""
+ # handle multiline msgid if we're in one
+ if self.inmultilinemsgid:
+ msgid = quote.rstripeol(line).strip()
+ # see if there's more
+ self.inmultilinemsgid = (msgid[-1:] == '\\')
+ # if we're echoing...
+ if self.inecho:
+ returnline = line
+ # otherwise, this could be a comment
+ elif line.strip()[:1] == '#':
+ returnline = quote.rstripeol(line)+eol
+ else:
+ line = quote.rstripeol(line)
+ equalspos = line.find('=')
+ # if no equals, just repeat it
+ if equalspos == -1:
+ returnline = quote.rstripeol(line)+eol
+ # otherwise, this is a definition
+ else:
+ # backslash at end means carry string on to next line
+ if quote.rstripeol(line)[-1:] == '\\':
+ self.inmultilinemsgid = True
+ # now deal with the current string...
+ key = line[:equalspos].strip()
+ # Calculate space around the equal sign
+ prespace = line.lstrip()[line.lstrip().find(' '):equalspos]
+ postspacestart = len(line[equalspos+1:])
+ postspaceend = len(line[equalspos+1:].lstrip())
+ postspace = line[equalspos+1:equalspos+(postspacestart-postspaceend)+1]
+ if self.inputdict.has_key(key):
+ self.inecho = False
+ value = self.inputdict[key]
+ if isinstance(value, str):
+ value = value.decode('utf8')
+ if self.personality == "mozilla":
+ returnline = key+prespace+"="+postspace+quote.mozillapropertiesencode(value)+eol
+ else:
+ returnline = key+prespace+"="+postspace+quote.javapropertiesencode(value)+eol
+ else:
+ self.inecho = True
+ returnline = line+eol
+ if isinstance(returnline, unicode):
+ returnline = returnline.encode('utf-8')
+ return returnline
+
+def convertmozillaprop(inputfile, outputfile, templatefile, includefuzzy=False):
+ """Mozilla specific convertor function"""
+ return convertprop(inputfile, outputfile, templatefile, personality="mozilla", includefuzzy=includefuzzy)
+
+def convertprop(inputfile, outputfile, templatefile, personality, includefuzzy=False):
+ inputstore = po.pofile(inputfile)
+ if templatefile is None:
+ raise ValueError("must have template file for properties files")
+ # convertor = po2prop()
+ else:
+ convertor = reprop(templatefile)
+ outputproplines = convertor.convertstore(inputstore, personality, includefuzzy)
+ outputfile.writelines(outputproplines)
+ return 1
+
+def main(argv=None):
+ # handle command line options
+ from translate.convert import convert
+ formats = {("po", "properties"): ("properties", convertprop)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ parser.add_option("", "--personality", dest="personality", default="java", type="choice",
+ choices=["java", "mozilla"],
+ help="set the output behaviour: java (default), mozilla", metavar="TYPE")
+ parser.add_fuzzy_option()
+ parser.passthrough.append("personality")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2rc b/translate-toolkit-1.5.1/translate/convert/po2rc
new file mode 100755
index 0000000..2f7bf05
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2rc
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+#
+# Copyright 2002, 2003, 2008 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a Gettext PO localization file to a Windows
+Resource (.rc) file"""
+
+from translate.convert import po2rc
+
+if __name__ == '__main__':
+ po2rc.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2rc.py b/translate-toolkit-1.5.1/translate/convert/po2rc.py
new file mode 100644
index 0000000..7d5219c
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2rc.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2006,2008-2009 Zuza Software Foundation
+#
+# This file is part of the Translate Toolkit.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+"""Convert Gettext PO localization files back to Windows Resource (.rc) files
+
+See: http://translate.sourceforge.net/wiki/toolkit/po2rc for examples and
+usage instructions.
+"""
+
+from translate.storage import po
+from translate.storage import rc
+
+class rerc:
+ def __init__(self, templatefile, charset="utf-8", lang=None, sublang=None):
+ self.templatefile = templatefile
+ self.templatestore = rc.rcfile(templatefile)
+ self.inputdict = {}
+ self.charset = charset
+ self.lang = lang
+ self.sublang = sublang
+
+ def convertstore(self, inputstore, includefuzzy=False):
+ self.makestoredict(inputstore, includefuzzy)
+ outputblocks = []
+ for block in self.templatestore.blocks:
+ outputblocks.append(self.convertblock(block))
+ if self.charset == "utf-8":
+ outputblocks.insert(0, "#pragma code_page(65001)\n")
+ outputblocks.append("#pragma code_page(default)")
+ return outputblocks
+
+ def makestoredict(self, store, includefuzzy=False):
+ """ make a dictionary of the translations"""
+ for unit in store.units:
+ if includefuzzy or not unit.isfuzzy():
+ for location in unit.getlocations():
+ rcstring = unit.target
+ if len(rcstring.strip()) == 0:
+ rcstring = unit.source
+ self.inputdict[location] = rc.escape_to_rc(rcstring).encode(self.charset)
+
+ def convertblock(self, block):
+ newblock = block
+ if isinstance(newblock, unicode):
+ newblock = newblock.encode('utf-8')
+ if newblock.startswith("LANGUAGE"):
+ return "LANGUAGE %s, %s" % (self.lang, self.sublang)
+ for unit in self.templatestore.units:
+ location = unit.getlocations()[0]
+ if self.inputdict.has_key(location):
+ if self.inputdict[location] != unit.match.groupdict()['value']:
+ newmatch = unit.match.group().replace(unit.match.groupdict()['value'], self.inputdict[location])
+ newblock = newblock.replace(unit.match.group(), newmatch)
+ if isinstance(newblock, unicode):
+ newblock = newblock.encode(self.charset)
+ return newblock
+
+def convertrc(inputfile, outputfile, templatefile, includefuzzy=False, charset=None, lang=None, sublang=None):
+ inputstore = po.pofile(inputfile)
+ if not lang:
+ raise ValueError("must specify a target language")
+ if templatefile is None:
+ raise ValueError("must have template file for rc files")
+ # convertor = po2rc()
+ else:
+ convertor = rerc(templatefile, charset, lang, sublang)
+ outputrclines = convertor.convertstore(inputstore, includefuzzy)
+ outputfile.writelines(outputrclines)
+ return 1
+
+def main(argv=None):
+ # handle command line options
+ from translate.convert import convert
+ formats = {("po", "rc"): ("rc", convertrc)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ defaultcharset = "utf-8"
+ parser.add_option("", "--charset", dest="charset", default=defaultcharset,
+ help="charset to use to decode the RC files (default: %s)" % defaultcharset, metavar="CHARSET")
+ parser.add_option("-l", "--lang", dest="lang", default=None,
+ help="LANG entry", metavar="LANG")
+ defaultsublang="SUBLANG_DEFAULT"
+ parser.add_option("", "--sublang", dest="sublang", default=defaultsublang,
+ help="SUBLANG entry (default: %s)" % defaultsublang, metavar="SUBLANG")
+ parser.passthrough.append("charset")
+ parser.passthrough.append("lang")
+ parser.passthrough.append("sublang")
+ parser.add_fuzzy_option()
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2sub b/translate-toolkit-1.5.1/translate/convert/po2sub
new file mode 100755
index 0000000..9060d4f
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2sub
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a gettext .po localization file to a supported subtitle file"""
+
+from translate.convert import po2sub
+
+if __name__ == '__main__':
+ po2sub.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2sub.py b/translate-toolkit-1.5.1/translate/convert/po2sub.py
new file mode 100644
index 0000000..4cffde4
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2sub.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008-2009 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+"""Convert Gettext PO localization files to subtitle files"""
+
+from translate.storage import factory
+from translate.storage import subtitles
+
+class resub:
+ def __init__(self, templatefile):
+ self.templatefile = templatefile
+ self.templatestore = subtitles.SubtitleFile(templatefile)
+ self._inputdict = {}
+
+ def convertstore(self, inputstore, includefuzzy=False):
+ self._makestoredict(inputstore, includefuzzy)
+ for unit in self.templatestore.units:
+ for location in unit.getlocations():
+ if location in self._inputdict:
+ unit.target = self._inputdict[location]
+ else:
+ unit.target = unit.source
+ return str(self.templatestore)
+
+ def _makestoredict(self, store, includefuzzy=False):
+ # make a dictionary of the translations
+ for unit in store.units:
+ if includefuzzy or not unit.isfuzzy():
+ # there may be more than one entity due to msguniq merge
+ for location in unit.getlocations():
+ substring = unit.target
+ if len(substring.strip()) == 0:
+ substring = unit.source
+ self._inputdict[location] = substring
+
+def convertsub(inputfile, outputfile, templatefile, includefuzzy=False):
+ inputstore = factory.getobject(inputfile)
+ if templatefile is None:
+ raise ValueError("must have template file for subtitle files")
+ else:
+ convertor = resub(templatefile)
+ outputstring = convertor.convertstore(inputstore, includefuzzy)
+ outputfile.write(outputstring)
+ return 1
+
+def main(argv=None):
+ # handle command line options
+ from translate.convert import convert
+ formats = {("po", "srt"): ("srt", convertsub)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ parser.add_fuzzy_option()
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2symb b/translate-toolkit-1.5.1/translate/convert/po2symb
new file mode 100755
index 0000000..fae60c1
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2symb
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of the Translate Toolkit.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+"""Convert a gettext .po localization file to a Symbian localisation file"""
+
+from translate.convert import po2symb
+
+if __name__ == '__main__':
+ po2symb.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2symb.py b/translate-toolkit-1.5.1/translate/convert/po2symb.py
new file mode 100644
index 0000000..a202446
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2symb.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of the Translate Toolkit.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+"""convert Gettext PO localization files to Symbian translation files."""
+
+import sys
+from translate.storage import factory
+from translate.storage.pypo import po_escape_map
+from translate.storage.symbian import *
+
+def escape(text):
+ for key, val in po_escape_map.iteritems():
+ text = text.replace(key, val)
+ return '"%s"' % text
+
+def replace_header_items(ps, replacments):
+ match = read_while(ps, header_item_or_end_re.match, lambda match: match is None)
+ while not ps.current_line.startswith('*/'):
+ match = header_item_re.match(ps.current_line)
+ if match is not None:
+ key = match.groupdict()['key']
+ if key in replacments:
+ ps.current_line = match.expand('\g<key>\g<space>%s\n' % replacments[key])
+ ps.read_line()
+
+def parse(ps, header_replacements, body_replacements):
+ replace_header_items(ps, header_replacements)
+ try:
+ while True:
+ eat_whitespace(ps)
+ skip_no_translate(ps)
+ match = string_entry_re.match(ps.current_line)
+ if match is not None:
+ key = match.groupdict()['id']
+ if key in body_replacements:
+ value = body_replacements[key].target or body_replacements[key].source
+ ps.current_line = match.expand(u'\g<start>\g<id>\g<space>%s\n' % escape(value))
+ ps.read_line()
+ except StopIteration:
+ pass
+
+def line_saver(charset):
+ result = []
+ def save_line(line):
+ result.append(line.encode(charset))
+ return result, save_line
+
+def write_symbian(f, header_replacements, body_replacements):
+ lines = list(f)
+ charset = read_charset(lines)
+ result, save_line = line_saver(charset)
+ parse(ParseState(iter(lines), charset, save_line), header_replacements, body_replacements)
+ return result
+
+def build_location_index(store):
+ po_header = store.parseheader()
+ index = {}
+ for unit in store.units:
+ for location in unit.getlocations():
+ index[location] = unit
+ index['r_string_languagegroup_name'] = store.UnitClass(po_header['Language-Team'])
+ return index
+
+def build_header_index(store):
+ po_header = store.parseheader()
+ return {'Author': po_header['Last-Translator']}
+
+def convert_symbian(input_file, output_file, template_file, pot=False, duplicatestyle="msgctxt"):
+ store = factory.getobject(input_file)
+ location_index = build_location_index(store)
+ header_index = build_header_index(store)
+ output = write_symbian(template_file, header_index, location_index)
+ for line in output:
+ output_file.write(line)
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"po": ("r0", convert_symbian)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__)
+ parser.add_duplicates_option()
+ parser.passthrough.append("pot")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2tiki b/translate-toolkit-1.5.1/translate/convert/po2tiki
new file mode 100644
index 0000000..f63af7d
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2tiki
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Mozilla Corporation, Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a gettext .po localization file to a TikiWiki style language.php file"""
+
+from translate.convert import po2tiki
+
+if __name__ == '__main__':
+ po2tiki.main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2tiki.py b/translate-toolkit-1.5.1/translate/convert/po2tiki.py
new file mode 100644
index 0000000..4860174
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2tiki.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Mozilla Corporation, Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+""" Convert .po files to TikiWiki's language.php files. """
+
+import sys
+from translate.storage import tiki
+from translate.storage import po
+
+class po2tiki:
+ def convertstore(self, thepofile):
+ """Converts a given (parsed) po file to a tiki file.
+
+ @param thepofile: a pofile pre-loaded with input data
+ """
+ thetargetfile = tiki.TikiStore()
+ for unit in thepofile.units:
+ if not (unit.isblank() or unit.isheader()):
+ newunit = tiki.TikiUnit(unit.source)
+ newunit.settarget(unit.target)
+ locations = unit.getlocations()
+ if locations:
+ newunit.addlocations(locations)
+ # If a word is "untranslated" but the target isn't empty and isn't the same as the source
+ # it's been translated and we switch it. This is an assumption but should remain true as long
+ # as these scripts are used.
+ if newunit.getlocations() == ["untranslated"] and unit.source != unit.target and unit.target != "":
+ newunit.location = []
+ newunit.addlocation("translated")
+
+ thetargetfile.addunit(newunit)
+ return thetargetfile
+
+def convertpo(inputfile, outputfile, template=None):
+ """Converts from po file format to tiki.
+
+ @param inputfile: file handle of the source
+ @param outputfile: file handle to write to
+ @param template: unused
+ """
+ inputstore = po.pofile(inputfile)
+ if inputstore.isempty():
+ return False
+ convertor = po2tiki()
+ outputstore = convertor.convertstore(inputstore)
+ outputfile.write(str(outputstore))
+ return True
+
+def main(argv=None):
+ """Will convert from .po to tiki style .php"""
+ from translate.convert import convert
+ from translate.misc import stdiotell
+ sys.stdout = stdiotell.StdIOWrapper(sys.stdout)
+
+ formats = {"po":("tiki",convertpo)}
+
+ parser = convert.ConvertOptionParser(formats, description=__doc__)
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2tmx b/translate-toolkit-1.5.1/translate/convert/po2tmx
new file mode 100755
index 0000000..3915aa5
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2tmx
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2005 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Converts Gettext .po files to Qt .ts localization files
+You can convert from .ts to .po using po2ts"""
+
+from translate.convert import po2tmx
+
+if __name__ == '__main__':
+ po2tmx.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2tmx.py b/translate-toolkit-1.5.1/translate/convert/po2tmx.py
new file mode 100644
index 0000000..82a0314
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2tmx.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2005, 2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert Gettext PO localization files to a TMX (Translation Memory eXchange) file
+
+see: http://translate.sourceforge.net/wiki/toolkit/po2tmx for examples and
+usage instructions
+"""
+
+from translate.storage import po
+from translate.storage import tmx
+from translate.convert import convert
+from translate.misc import wStringIO
+import os
+
+class po2tmx:
+ def convertfile(self, inputfile, sourcelanguage='en', targetlanguage=None):
+ """converts a .po file to TMX file"""
+ # TODO: This seems to not be used... remove it
+ inputstore = inputfile
+ for inunit in inputstore.units:
+ if inunit.isheader() or inunit.isblank() or not inunit.istranslated() or inunit.isfuzzy():
+ continue
+ source = inunit.source
+ translation = inunit.target
+ # TODO place source location in comments
+ tmxfile.addtranslation(source, sourcelanguage, translation, targetlanguage)
+ return str(tmxfile)
+
+ def convertfiles(self, inputfile, tmxfile, sourcelanguage='en', targetlanguage=None):
+ """converts a .po file (possibly many) to TMX file"""
+ inputstore = po.pofile(inputfile)
+ for inunit in inputstore.units:
+ if inunit.isheader() or inunit.isblank() or not inunit.istranslated() or inunit.isfuzzy():
+ continue
+ source = inunit.source
+ translation = inunit.target
+ # TODO place source location in comments
+ tmxfile.addtranslation(source, sourcelanguage, translation, targetlanguage)
+
+def convertpo(inputfile, outputfile, templatefile, sourcelanguage='en', targetlanguage=None):
+ """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout"""
+ convertor = po2tmx()
+ convertor.convertfiles(inputfile, outputfile.tmxfile, sourcelanguage, targetlanguage)
+ return 1
+
+class tmxmultifile:
+ def __init__(self, filename, mode=None):
+ """initialises tmxmultifile from a seekable inputfile or writable outputfile"""
+ self.filename = filename
+ if mode is None:
+ if os.path.exists(filename):
+ mode = 'r'
+ else:
+ mode = 'w'
+ self.mode = mode
+# self.multifilestyle = multifilestyle
+ self.multifilename = os.path.splitext(filename)[0]
+# self.multifile = open(filename, mode)
+ self.tmxfile = tmx.tmxfile()
+
+ def openoutputfile(self, subfile):
+ """returns a pseudo-file object for the given subfile"""
+ def onclose(contents):
+ pass
+ outputfile = wStringIO.CatchStringOutput(onclose)
+ outputfile.filename = subfile
+ outputfile.tmxfile = self.tmxfile
+ return outputfile
+
+
+class TmxOptionParser(convert.ArchiveConvertOptionParser):
+ def recursiveprocess(self, options):
+ if not options.targetlanguage:
+ raise ValueError("You must specify the target language")
+ super(TmxOptionParser, self).recursiveprocess(options)
+ self.output = open(options.output, 'w')
+ options.outputarchive.tmxfile.setsourcelanguage(options.sourcelanguage)
+ self.output.write(str(options.outputarchive.tmxfile))
+
+def main(argv=None):
+ formats = {"po": ("tmx", convertpo), ("po", "tmx"): ("tmx", convertpo)}
+ archiveformats = {(None, "output"): tmxmultifile, (None, "template"): tmxmultifile}
+ parser = TmxOptionParser(formats, usepots=False, usetemplates=False, description=__doc__, archiveformats=archiveformats)
+ parser.add_option("-l", "--language", dest="targetlanguage", default=None,
+ help="set target language code (e.g. af-ZA) [required]", metavar="LANG")
+ parser.add_option("", "--source-language", dest="sourcelanguage", default='en',
+ help="set source language code (default: en)", metavar="LANG")
+ parser.passthrough.append("sourcelanguage")
+ parser.passthrough.append("targetlanguage")
+ parser.run(argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2ts b/translate-toolkit-1.5.1/translate/convert/po2ts
new file mode 100755
index 0000000..e95fbe6
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2ts
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Converts Gettext .po files to Qt .ts localization files
+You can convert from .ts to .po using po2ts"""
+
+from translate.convert import po2ts
+
+if __name__ == '__main__':
+ po2ts.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2ts.py b/translate-toolkit-1.5.1/translate/convert/po2ts.py
new file mode 100644
index 0000000..4616051
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2ts.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert Gettext PO localization files to Qt Linguist (.ts) files
+
+see: http://translate.sourceforge.net/wiki/toolkit/po2ts for examples and
+usage instructions
+"""
+
+from translate.storage import po
+from translate.storage import ts
+
+class po2ts:
+ def convertstore(self, inputstore, templatefile=None, context=None):
+ """converts a .po file to .ts format (using a template .ts file if given)"""
+ if templatefile is None:
+ tsfile = ts.QtTsParser()
+ else:
+ tsfile = ts.QtTsParser(templatefile)
+ for inputunit in inputstore.units:
+ if inputunit.isheader() or inputunit.isblank():
+ continue
+ source = inputunit.source
+ translation = inputunit.target
+ comment = inputunit.getnotes("translator")
+ transtype = None
+ if not inputunit.istranslated():
+ transtype = "unfinished"
+ elif inputunit.getnotes("developer") == "(obsolete)":
+ transtype = "obsolete"
+ if isinstance(source, str):
+ source = source.decode("utf-8")
+ if isinstance(translation, str):
+ translation = translation.decode("utf-8")
+ for sourcelocation in inputunit.getlocations():
+ if context is None:
+ if "#" in sourcelocation:
+ contextname = sourcelocation[:sourcelocation.find("#")]
+ else:
+ contextname = sourcelocation
+ else:
+ contextname = context
+ tsfile.addtranslation(contextname, source, translation, comment, transtype, createifmissing=True)
+ return tsfile.getxml()
+
+def convertpo(inputfile, outputfile, templatefile, context):
+ """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout"""
+ inputstore = po.pofile(inputfile)
+ if inputstore.isempty():
+ return 0
+ convertor = po2ts()
+ outputstring = convertor.convertstore(inputstore, templatefile, context)
+ outputfile.write(outputstring)
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"po": ("ts", convertpo), ("po", "ts"): ("ts", convertpo)}
+ parser = convert.ConvertOptionParser(formats, usepots=False, usetemplates=True, description=__doc__)
+ parser.add_option("-c", "--context", dest="context", default=None,
+ help="use supplied context instead of the one in the .po file comment")
+ parser.passthrough.append("context")
+ parser.run(argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2txt b/translate-toolkit-1.5.1/translate/convert/po2txt
new file mode 100755
index 0000000..5e3ea45
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2txt
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""script to translate a set of plain text message files using gettext .po localization
+You can generate the po files using txt2po"""
+
+from translate.convert import po2txt
+
+if __name__ == '__main__':
+ po2txt.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2txt.py b/translate-toolkit-1.5.1/translate/convert/po2txt.py
new file mode 100644
index 0000000..3ec6353
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2txt.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert Gettext PO localization files to plain text (.txt) files
+
+see: http://translate.sourceforge.net/wiki/toolkit/po2txt for examples and
+usage instructions
+"""
+
+from translate.storage import factory
+try:
+ import textwrap
+except:
+ textwrap = None
+
+class po2txt:
+ """po2txt can take a po file and generate txt. best to give it a template file otherwise will just concat msgstrs"""
+ def __init__(self, wrap=None):
+ self.wrap = wrap
+
+ def wrapmessage(self, message):
+ """rewraps text as required"""
+ if self.wrap is None:
+ return message
+ return "\n".join([textwrap.fill(line, self.wrap, replace_whitespace=False) for line in message.split("\n")])
+
+ def convertstore(self, inputstore, includefuzzy):
+ """converts a file to txt format"""
+ txtresult = ""
+ for unit in inputstore.units:
+ if unit.isheader():
+ continue
+ if unit.istranslated() or (includefuzzy and unit.isfuzzy()):
+ txtresult += self.wrapmessage(unit.target) + "\n" + "\n"
+ else:
+ txtresult += self.wrapmessage(unit.source) + "\n" + "\n"
+ return txtresult.rstrip()
+
+ def mergestore(self, inputstore, templatetext, includefuzzy):
+ """converts a file to txt format"""
+ txtresult = templatetext
+ # TODO: make a list of blocks of text and translate them individually
+ # rather than using replace
+ for unit in inputstore.units:
+ if unit.isheader():
+ continue
+ if not unit.isfuzzy() or includefuzzy:
+ txtsource = unit.source
+ txttarget = self.wrapmessage(unit.target)
+ if unit.istranslated():
+ txtresult = txtresult.replace(txtsource, txttarget)
+ return txtresult
+
+def converttxt(inputfile, outputfile, templatefile, wrap=None, includefuzzy=False, encoding='utf-8'):
+ """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout"""
+ inputstore = factory.getobject(inputfile)
+ convertor = po2txt(wrap=wrap)
+ if templatefile is None:
+ outputstring = convertor.convertstore(inputstore, includefuzzy)
+ else:
+ templatestring = templatefile.read().decode(encoding)
+ outputstring = convertor.mergestore(inputstore, templatestring, includefuzzy)
+ outputfile.write(outputstring.encode('utf-8'))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ from translate.misc import stdiotell
+ import sys
+ sys.stdout = stdiotell.StdIOWrapper(sys.stdout)
+ formats = {("po", "txt"):("txt", converttxt), ("po"):("txt", converttxt), ("xlf", "txt"):("txt", converttxt), ("xlf"):("txt", converttxt)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ parser.add_option("", "--encoding", dest="encoding", default='utf-8', type="string",
+ help="The encoding of the template file (default: UTF-8)")
+ parser.passthrough.append("encoding")
+ if textwrap is not None:
+ parser.add_option("-w", "--wrap", dest="wrap", default=None, type="int",
+ help="set number of columns to wrap text at", metavar="WRAP")
+ parser.passthrough.append("wrap")
+ parser.add_fuzzy_option()
+ parser.run(argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2web2py b/translate-toolkit-1.5.1/translate/convert/po2web2py
new file mode 100755
index 0000000..5fbf9be
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2web2py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2009 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+"""convert GNU/gettext PO files to web2py translation dictionaries (.py)"""
+
+from translate.convert import po2web2py
+
+if __name__ == '__main__':
+ po2web2py.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2web2py.py b/translate-toolkit-1.5.1/translate/convert/po2web2py.py
new file mode 100644
index 0000000..6df690f
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2web2py.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2009 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# (c) 2009 Dominic König (dominic@nursix.org)
+#
+
+"""convert GNU/gettext PO files to web2py translation dictionaries (.py)"""
+
+from translate.storage import factory
+
+class po2pydict:
+ def __init__(self):
+ return
+
+ def convertstore(self, inputstore, includefuzzy):
+ from StringIO import StringIO
+ str_obj = StringIO()
+
+ mydict = dict()
+ for unit in inputstore.units:
+ if unit.isheader():
+ continue
+ if unit.istranslated() or (includefuzzy and unit.isfuzzy()):
+ mydict[unit.source] = unit.target
+ else:
+ mydict[unit.source] = '*** ' + unit.source
+
+ str_obj.write('{\n')
+ for source_str in mydict:
+ str_obj.write("%s:%s,\n" % (repr(str(source_str)),repr(str(mydict[source_str]))))
+ str_obj.write('}\n')
+ str_obj.seek(0)
+ return str_obj
+
+def convertpy(inputfile, outputfile, templatefile=None, includefuzzy=False):
+ inputstore = factory.getobject(inputfile)
+ convertor = po2pydict()
+ outputstring = convertor.convertstore(inputstore, includefuzzy)
+ outputfile.write(outputstring.read())
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ from translate.misc import stdiotell
+ import sys
+ sys.stdout = stdiotell.StdIOWrapper(sys.stdout)
+ formats = {("po", "py"):("py", convertpy), ("po"):("py", convertpy)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=False, description=__doc__)
+ parser.add_fuzzy_option()
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2wordfast b/translate-toolkit-1.5.1/translate/convert/po2wordfast
new file mode 100755
index 0000000..33e6988
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2wordfast
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Converts Gettext .po files to Wordfast Translation Memory files"""
+
+from translate.convert import po2wordfast
+
+if __name__ == '__main__':
+ po2wordfast.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2wordfast.py b/translate-toolkit-1.5.1/translate/convert/po2wordfast.py
new file mode 100644
index 0000000..db46196
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2wordfast.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2005-2007 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert Gettext PO localization files to a Wordfast translation memory file
+
+see: http://translate.sourceforge.net/wiki/toolkit/po2wordfast for examples and
+usage instructions
+"""
+
+from translate.storage import po
+from translate.storage import wordfast
+from translate.convert import convert
+from translate.misc import wStringIO
+import os
+
+class po2wordfast:
+ def convertfiles(self, inputfile, wffile, sourcelanguage='en', targetlanguage=None):
+ """converts a .po file (possibly many) to a Wordfast TM file"""
+ inputstore = po.pofile(inputfile)
+ for inunit in inputstore.units:
+ if inunit.isheader() or inunit.isblank() or not inunit.istranslated():
+ continue
+ source = inunit.source
+ target = inunit.target
+ newunit = wffile.addsourceunit(source)
+ newunit.target = target
+ newunit.targetlang = targetlanguage
+
+def convertpo(inputfile, outputfile, templatefile, sourcelanguage='en', targetlanguage=None):
+ """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout"""
+ convertor = po2wordfast()
+ outputfile.wffile.header.targetlang = targetlanguage
+ convertor.convertfiles(inputfile, outputfile.wffile, sourcelanguage, targetlanguage)
+ return 1
+
+class wfmultifile:
+ def __init__(self, filename, mode=None):
+ """initialises wfmultifile from a seekable inputfile or writable outputfile"""
+ self.filename = filename
+ if mode is None:
+ if os.path.exists(filename):
+ mode = 'r'
+ else:
+ mode = 'w'
+ self.mode = mode
+ self.multifilename = os.path.splitext(filename)[0]
+ self.wffile = wordfast.WordfastTMFile()
+
+ def openoutputfile(self, subfile):
+ """returns a pseudo-file object for the given subfile"""
+ def onclose(contents):
+ pass
+ outputfile = wStringIO.CatchStringOutput(onclose)
+ outputfile.filename = subfile
+ outputfile.wffile = self.wffile
+ return outputfile
+
+
+class WfOptionParser(convert.ArchiveConvertOptionParser):
+ def recursiveprocess(self, options):
+ if not options.targetlanguage:
+ raise ValueError("You must specify the target language")
+ super(WfOptionParser, self).recursiveprocess(options)
+ self.output = open(options.output, 'w')
+ #options.outputarchive.wffile.setsourcelanguage(options.sourcelanguage)
+ self.output.write(str(options.outputarchive.wffile))
+
+def main(argv=None):
+ formats = {"po": ("txt", convertpo), ("po", "txt"): ("txt", convertpo)}
+ archiveformats = {(None, "output"): wfmultifile, (None, "template"): wfmultifile}
+ parser = WfOptionParser(formats, usepots=False, usetemplates=False, description=__doc__, archiveformats=archiveformats)
+ parser.add_option("-l", "--language", dest="targetlanguage", default=None,
+ help="set target language code (e.g. af-ZA) [required]", metavar="LANG")
+ parser.add_option("", "--source-language", dest="sourcelanguage", default='en',
+ help="set source language code (default: en)", metavar="LANG")
+ parser.passthrough.append("sourcelanguage")
+ parser.passthrough.append("targetlanguage")
+ parser.run(argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/po2xliff b/translate-toolkit-1.5.1/translate/convert/po2xliff
new file mode 100755
index 0000000..fac5eb0
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2xliff
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2005 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Converts Gettext .po files to .xliff localization files
+You can convert from .xliff to .po using po2xliff"""
+
+from translate.convert import po2xliff
+
+if __name__ == '__main__':
+ po2xliff.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/po2xliff.py b/translate-toolkit-1.5.1/translate/convert/po2xliff.py
new file mode 100644
index 0000000..4fdc77a
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/po2xliff.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2005, 2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert Gettext PO localization files to XLIFF localization files
+
+see: http://translate.sourceforge.net/wiki/toolkit/po2xliff for examples and
+usage instructions
+"""
+
+from translate.storage import po
+from translate.storage import poxliff
+
+class po2xliff:
+ def convertunit(self, outputstore, inputunit, filename):
+ """creates a transunit node"""
+ source = inputunit.source
+ target = inputunit.target
+ if inputunit.isheader():
+ unit = outputstore.addheaderunit(target, filename)
+ else:
+ unit = outputstore.addsourceunit(source, filename, True)
+ unit.target = target
+ #Explicitly marking the fuzzy state will ensure that normal (translated)
+ #units in the PO file end up as approved in the XLIFF file.
+ if target:
+ unit.markfuzzy(inputunit.isfuzzy())
+ else:
+ unit.markapproved(False)
+
+ #Handle #: location comments
+ for location in inputunit.getlocations():
+ unit.createcontextgroup("po-reference", self.contextlist(location), purpose="location")
+
+ #Handle #. automatic comments
+ comment = inputunit.getnotes("developer")
+ if comment:
+ unit.createcontextgroup("po-entry", [("x-po-autocomment", comment)], purpose="information")
+ unit.addnote(comment, origin="developer")
+
+ #TODO: x-format, etc.
+
+
+ #Handle # other comments
+ comment = inputunit.getnotes("translator")
+ if comment:
+ unit.createcontextgroup("po-entry", [("x-po-trancomment", comment)], purpose="information")
+ unit.addnote(comment, origin="po-translator")
+
+ return unit
+
+ def contextlist(self, location):
+ contexts = []
+ if ":" in location:
+ sourcefile, linenumber = location.split(":", 1)
+ else:
+ sourcefile, linenumber = location, None
+ contexts.append(("sourcefile", sourcefile))
+ if linenumber:
+ contexts.append(("linenumber", linenumber))
+ return contexts
+
+ def convertstore(self, inputstore, templatefile=None, **kwargs):
+ """converts a .po file to .xlf format"""
+ if templatefile is None:
+ outputstore = poxliff.PoXliffFile(**kwargs)
+ else:
+ outputstore = poxliff.PoXliffFile(templatefile, **kwargs)
+ filename = inputstore.filename
+ for inputunit in inputstore.units:
+ if inputunit.isblank():
+ continue
+ transunitnode = self.convertunit(outputstore, inputunit, filename)
+ return str(outputstore)
+
+def convertpo(inputfile, outputfile, templatefile):
+ """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout"""
+ inputstore = po.pofile(inputfile)
+ if inputstore.isempty():
+ return 0
+ convertor = po2xliff()
+ outputstring = convertor.convertstore(inputstore, templatefile)
+ outputfile.write(outputstring)
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"po": ("xlf", convertpo), ("po", "xlf"): ("xlf", convertpo)}
+ parser = convert.ConvertOptionParser(formats, usepots=True, usetemplates=True, description=__doc__)
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/poreplace.py b/translate-toolkit-1.5.1/translate/convert/poreplace.py
new file mode 100644
index 0000000..4df9841
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/poreplace.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to do replacements on translated strings inside po files"""
+
+# this is used as the basis for other scripts, it currently replaces nothing
+
+from translate.storage import po
+
+class poreplace:
+ def convertstring(self, postr):
+ """does the conversion required on the given string (nothing in this case)"""
+ return postr
+
+ def convertfile(self, thepofile):
+ """goes through a po file and converts each element"""
+ for thepo in thepofile.units:
+ thepo.msgstr = [self.convertstring(postr) for postr in thepo.msgstr]
+ return thepofile
+
+ def convertpo(self, inputfile, outputfile, templatefile):
+ """reads in inputfile using po, converts using poreplace, writes to outputfile"""
+ # note that templatefile is not used, but it is required by the converter...
+ inputstore = po.pofile(inputfile)
+ if inputstore.isempty():
+ return 0
+ outputstore = self.convertfile(inputstore)
+ if outputstore.isempty():
+ return 0
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(converterclass, argv=None):
+ # handle command line options
+ from translate.convert import convert
+ replacer = converterclass()
+ formats = {"po":("po", replacer.convertpo), "pot":("pot", replacer.convertpo)}
+ parser = convert.ConvertOptionParser(formats, usepots=True)
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main(poreplace)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/pot2po b/translate-toolkit-1.5.1/translate/convert/pot2po
new file mode 100755
index 0000000..3b6cf72
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/pot2po
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""convert a gettext .pot template to a .po translation file, merging in existing translations if present"""
+
+from translate.convert import pot2po
+
+if __name__ == '__main__':
+ pot2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/pot2po.py b/translate-toolkit-1.5.1/translate/convert/pot2po.py
new file mode 100644
index 0000000..1150e93
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/pot2po.py
@@ -0,0 +1,253 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2009 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+"""Convert template files (like .pot or template .xlf files) translation files,
+preserving existing translations.
+
+See: http://translate.sourceforge.net/wiki/toolkit/pot2po for examples and
+usage instructions.
+"""
+
+from translate.storage import factory
+from translate.search import match
+from translate.misc.multistring import multistring
+from translate.tools import pretranslate
+from translate.storage import poheader
+
+
+def convertpot(input_file, output_file, template_file, tm=None, min_similarity=75, fuzzymatching=True, **kwargs):
+ """Main conversion function"""
+
+ input_store = factory.getobject(input_file)
+ template_store = None
+ if template_file is not None:
+ template_store = factory.getobject(template_file)
+ output_store = convert_stores(input_store, template_store, tm, min_similarity, fuzzymatching, **kwargs)
+ output_file.write(str(output_store))
+ return 1
+
+def convert_stores(input_store, template_store, tm=None, min_similarity=75, fuzzymatching=True, **kwargs):
+ """Actual conversion function, works on stores not files, returns
+ a properly initialized pretranslated output store, with structure
+ based on input_store, metadata based on template_store, migrates
+ old translations from template_store and pretranslating from tm"""
+
+ #prepare for merging
+ output_store = type(input_store)()
+ #create fuzzy matchers to be used by pretranslate.pretranslate_unit
+ matchers = []
+ _prepare_merge(input_store, output_store, template_store)
+ if fuzzymatching:
+ if template_store:
+ matcher = match.matcher(template_store, max_candidates=1, min_similarity=min_similarity, max_length=3000, usefuzzy=True)
+ matcher.addpercentage = False
+ matchers.append(matcher)
+ if tm:
+ matcher = pretranslate.memory(tm, max_candidates=1, min_similarity=min_similarity, max_length=1000)
+ matcher.addpercentage = False
+ matchers.append(matcher)
+
+ #initialize store
+ _store_pre_merge(input_store, output_store, template_store)
+
+ # Do matching
+ for input_unit in input_store.units:
+ if input_unit.istranslatable():
+ input_unit = pretranslate.pretranslate_unit(input_unit, template_store, matchers, mark_reused=True)
+ _unit_post_merge(input_unit, input_store, output_store, template_store)
+ output_store.addunit(input_unit)
+
+ #finalize store
+ _store_post_merge(input_store, output_store, template_store)
+
+ return output_store
+
+
+##dispatchers
+def _prepare_merge(input_store, output_store, template_store, **kwargs):
+ """Prepare stores & TM matchers before merging."""
+ #dispatch to format specific functions
+ prepare_merge_hook = "_prepare_merge_%s" % input_store.__class__.__name__
+ if globals().has_key(prepare_merge_hook):
+ globals()[prepare_merge_hook](input_store, output_store, template_store, **kwargs)
+
+ #generate an index so we can search by source string and location later on
+ input_store.makeindex()
+ if template_store:
+ template_store.makeindex()
+
+
+def _store_pre_merge(input_store, output_store, template_store, **kwargs) :
+ """Initialize the new file with things like headers and metadata."""
+ #formats that implement poheader interface are a special case
+ if isinstance(input_store, poheader.poheader):
+ _do_poheaders(input_store, output_store, template_store)
+
+ #dispatch to format specific functions
+ store_pre_merge_hook = "_store_pre_merge_%s" % input_store.__class__.__name__
+ if globals().has_key(store_pre_merge_hook):
+ globals()[store_pre_merge_hook](input_store, output_store, template_store, **kwargs)
+
+
+def _store_post_merge(input_store, output_store, template_store, **kwargs) :
+ """Close file after merging all translations, used for adding
+ statistics, obsolete messages and similar wrapup tasks."""
+ #dispatch to format specific functions
+ store_post_merge_hook = "_store_post_merge_%s" % input_store.__class__.__name__
+ if globals().has_key(store_post_merge_hook):
+ globals()[store_post_merge_hook](input_store, output_store, template_store, **kwargs)
+
+def _unit_post_merge(input_unit, input_store, output_store, template_store, **kwargs):
+ """Handle any unit level cleanup and situations not handled by the merge()
+ function."""
+ #dispatch to format specific functions
+ unit_post_merge_hook = "_unit_post_merge_%s" % input_unit.__class__.__name__
+ if globals().has_key(unit_post_merge_hook):
+ globals()[unit_post_merge_hook](input_unit, input_store, output_store, template_store, **kwargs)
+
+
+##format specific functions
+def _prepare_merge_pofile(input_store, output_store, template_store):
+ """PO format specific template preparation logic."""
+ #we need to revive obsolete units to be able to consider
+ #their translation when matching
+ if template_store:
+ for unit in template_store.units:
+ if unit.isobsolete():
+ unit.resurrect()
+
+
+def _unit_post_merge_pounit(input_unit, input_store, output_store, template_store):
+ """PO format specific plural string initializtion logic."""
+ #FIXME: do we want to do that for poxliff also?
+ if input_unit.hasplural() and len(input_unit.target) == 0:
+ # untranslated plural unit; Let's ensure that we have the correct number of plural forms:
+ nplurals, plural = output_store.getheaderplural()
+ if nplurals and nplurals.isdigit() and nplurals != '2':
+ input_unit.target = multistring([""]*int(nplurals))
+
+
+def _store_post_merge_pofile(input_store, output_store, template_store):
+ """PO format specific: adds newly obsoleted messages to end of store."""
+ #Let's take care of obsoleted messages
+ if template_store:
+ newlyobsoleted = []
+ for unit in template_store.units:
+ if unit.isheader():
+ continue
+ if unit.target and not (input_store.findunit(unit.source) or hasattr(unit, "reused")):
+ #not in .pot, make it obsolete
+ unit.makeobsolete()
+ newlyobsoleted.append(unit)
+ elif unit.isobsolete():
+ output_store.addunit(unit)
+ for unit in newlyobsoleted:
+ output_store.addunit(unit)
+
+
+def _do_poheaders(input_store, output_store, template_store):
+ """Adds initialized PO headers to output store."""
+ # header values
+ charset = "UTF-8"
+ encoding = "8bit"
+ project_id_version = None
+ pot_creation_date = None
+ po_revision_date = None
+ last_translator = None
+ language_team = None
+ mime_version = None
+ plural_forms = None
+ kwargs = {}
+
+ if template_store is not None and isinstance(template_store, poheader.poheader):
+ templateheadervalues = template_store.parseheader()
+ for key, value in templateheadervalues.iteritems():
+ if key == "Project-Id-Version":
+ project_id_version = value
+ elif key == "Last-Translator":
+ last_translator = value
+ elif key == "Language-Team":
+ language_team = value
+ elif key == "PO-Revision-Date":
+ po_revision_date = value
+ elif key in ("POT-Creation-Date", "MIME-Version"):
+ # don't know how to handle these keys, or ignoring them
+ pass
+ elif key == "Content-Type":
+ kwargs[key] = value
+ elif key == "Content-Transfer-Encoding":
+ encoding = value
+ elif key == "Plural-Forms":
+ plural_forms = value
+ else:
+ kwargs[key] = value
+
+ inputheadervalues = input_store.parseheader()
+ for key, value in inputheadervalues.iteritems():
+ if key in ("Project-Id-Version", "Last-Translator", "Language-Team", "PO-Revision-Date", "Content-Type", "Content-Transfer-Encoding", "Plural-Forms"):
+ # want to carry these from the template so we ignore them
+ pass
+ elif key == "POT-Creation-Date":
+ pot_creation_date = value
+ elif key == "MIME-Version":
+ mime_version = value
+ else:
+ kwargs[key] = value
+
+ output_header = output_store.makeheader(charset=charset, encoding=encoding, project_id_version=project_id_version,
+ pot_creation_date=pot_creation_date, po_revision_date=po_revision_date, last_translator=last_translator,
+ language_team=language_team, mime_version=mime_version, plural_forms=plural_forms, **kwargs)
+
+ # Get the header comments and fuzziness state
+ if template_store is not None and len(template_store.units) > 0:
+ if template_store.units[0].isheader():
+ if template_store.units[0].getnotes("translator"):
+ output_header.addnote(template_store.units[0].getnotes("translator"), "translator")
+ if input_store.units[0].getnotes("developer"):
+ output_header.addnote(input_store.units[0].getnotes("developer"), "developer")
+ output_header.markfuzzy(template_store.units[0].isfuzzy())
+ elif len(input_store.units) > 0 and input_store.units[0].isheader():
+ output_header.addnote(input_store.units[0].getnotes())
+
+ output_store.addunit(output_header)
+
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"pot": ("po", convertpot), ("pot", "po"): ("po", convertpot),
+ "xlf": ("xlf", convertpot), ("xlf", "xlf"): ("xlf", convertpot),
+ }
+ parser = convert.ConvertOptionParser(formats, usepots=True, usetemplates=True,
+ allowmissingtemplate=True, description=__doc__)
+ parser.add_option("", "--tm", dest="tm", default=None,
+ help="The file to use as translation memory when fuzzy matching")
+ parser.passthrough.append("tm")
+ defaultsimilarity = 75
+ parser.add_option("-s", "--similarity", dest="min_similarity", default=defaultsimilarity,
+ type="float", help="The minimum similarity for inclusion (default: %d%%)" % defaultsimilarity)
+ parser.passthrough.append("min_similarity")
+ parser.add_option("--nofuzzymatching", dest="fuzzymatching", action="store_false",
+ default=True, help="Disable fuzzy matching")
+ parser.passthrough.append("fuzzymatching")
+ parser.run(argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/prop2mozfunny.py b/translate-toolkit-1.5.1/translate/convert/prop2mozfunny.py
new file mode 100644
index 0000000..f938cee
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/prop2mozfunny.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2005, 2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""converts properties files back to funny mozilla files"""
+
+from translate.storage import properties
+from translate.convert import po2prop
+from translate.convert import mozfunny2prop
+from translate.misc.wStringIO import StringIO
+
+def prop2inc(pf):
+ """convert a properties file back to a .inc file with #defines in it"""
+ # any leftover blanks will not be included at the end
+ pendingblanks = []
+ for unit in pf.units:
+ for comment in unit.comments:
+ if comment.startswith("# converted from") and "#defines" in comment:
+ pass
+ else:
+ for blank in pendingblanks:
+ yield blank
+ # TODO: could convert commented # x=y back to # #define x y
+ yield comment
+ if unit.isblank():
+ pendingblanks.append("\n")
+ else:
+ definition = "#define %s %s\n" % (unit.name, unit.value.replace("\n", "\\n"))
+ if isinstance(definition, unicode):
+ definition = definition.encode("UTF-8")
+ for blank in pendingblanks:
+ yield blank
+ yield definition
+
+def prop2it(pf):
+ """convert a properties file back to a pseudo-properties .it file"""
+ for unit in pf.units:
+ for comment in unit.comments:
+ if comment.startswith("# converted from") and "pseudo-properties" in comment:
+ pass
+ elif comment.startswith("# section: "):
+ yield comment.replace("# section: ", "", 1) + "\n"
+ else:
+ yield comment.replace("#", ";", 1) + "\n"
+ if unit.isblank():
+ yield ""
+ else:
+ definition = "%s=%s\n" % (unit.name, unit.value)
+ if isinstance(definition, unicode):
+ definition = definition.encode("UTF-8")
+ yield definition
+
+def prop2funny(src, itencoding="cp1252"):
+ lines = src.split("\n")
+ header = lines[0]
+ if not header.startswith("# converted from "):
+ waspseudoprops = len([line for line in lines if line.startswith("# section:")])
+ wasdefines = len([line for line in lines if line.startswith("#filter") or line.startswith("#unfilter")])
+ else:
+ waspseudoprops = "pseudo-properties" in header
+ wasdefines = "#defines" in header
+ lines = lines[1:]
+ if not (waspseudoprops ^ wasdefines):
+ raise ValueError("could not determine file type as pseudo-properties or defines file")
+ pf = properties.propfile(personality="mozilla")
+ pf.parse("\n".join(lines))
+ if wasdefines:
+ for line in prop2inc(pf):
+ yield line + "\n"
+ elif waspseudoprops:
+ for line in prop2it(pf):
+ yield line.decode("utf-8").encode(itencoding) + "\n"
+
+def po2inc(inputfile, outputfile, templatefile, encoding=None, includefuzzy=False):
+ """wraps po2prop but converts outputfile to properties first"""
+ outputpropfile = StringIO()
+ if templatefile is not None:
+ templatelines = templatefile.readlines()
+ templateproplines = [line for line in mozfunny2prop.inc2prop(templatelines)]
+ templatepropfile = StringIO("".join(templateproplines))
+ else:
+ templatepropfile = None
+ result = po2prop.convertmozillaprop(inputfile, outputpropfile, templatepropfile, includefuzzy=includefuzzy)
+ if result:
+ outputpropfile.seek(0)
+ pf = properties.propfile(outputpropfile, personality="mozilla")
+ outputlines = prop2inc(pf)
+ outputfile.writelines(outputlines)
+ return result
+
+def po2it(inputfile, outputfile, templatefile, encoding="cp1252", includefuzzy=False):
+ """wraps po2prop but converts outputfile to properties first"""
+ outputpropfile = StringIO()
+ if templatefile is not None:
+ templatelines = templatefile.readlines()
+ templateproplines = [line for line in mozfunny2prop.it2prop(templatelines, encoding=encoding)]
+ templatepropfile = StringIO("".join(templateproplines))
+ else:
+ templatepropfile = None
+ result = po2prop.convertmozillaprop(inputfile, outputpropfile, templatepropfile, includefuzzy=includefuzzy)
+ if result:
+ outputpropfile.seek(0)
+ pf = properties.propfile(outputpropfile, personality="mozilla")
+ outputlines = prop2it(pf)
+ for line in outputlines:
+ line = line.decode("utf-8").encode(encoding)
+ outputfile.write(line)
+ return result
+
+def po2ini(inputfile, outputfile, templatefile, encoding="UTF-8", includefuzzy=False):
+ """wraps po2prop but converts outputfile to properties first using UTF-8 encoding"""
+ return po2it(inputfile=inputfile, outputfile=outputfile, templatefile=templatefile, encoding=encoding, includefuzzy=includefuzzy)
+
+def main(argv=None):
+ import sys
+ # TODO: get encoding from charset.mk, using parameter
+ src = sys.stdin.read()
+ for line in prop2funny(src):
+ sys.stdout.write(line)
+
+if __name__ == "__main__":
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/prop2po b/translate-toolkit-1.5.1/translate/convert/prop2po
new file mode 100755
index 0000000..b5d3678
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/prop2po
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2002, 2003 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a .properties file to a gettext .po localization file"""
+
+from translate.convert import prop2po
+
+if __name__ == '__main__':
+ prop2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/prop2po.py b/translate-toolkit-1.5.1/translate/convert/prop2po.py
new file mode 100644
index 0000000..d557667
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/prop2po.py
@@ -0,0 +1,167 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""convert Java/Mozilla .properties files to Gettext PO localization files
+
+See: http://translate.sourceforge.net/wiki/toolkit/prop2po for examples and
+usage instructions
+"""
+
+import sys
+from translate.storage import po
+from translate.storage import properties
+
+class prop2po:
+ """convert a .properties file to a .po file for handling the translation..."""
+ def convertstore(self, thepropfile, personality="java", duplicatestyle="msgctxt"):
+ """converts a .properties file to a .po file..."""
+ self.personality = personality
+ thetargetfile = po.pofile()
+ if self.personality == "mozilla":
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit", x_accelerator_marker="&")
+ else:
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit")
+ targetheader.addnote("extracted from %s" % thepropfile.filename, "developer")
+ # we try and merge the header po with any comments at the start of the properties file
+ appendedheader = False
+ waitingcomments = []
+ for propunit in thepropfile.units:
+ pounit = self.convertunit(propunit, "developer")
+ if pounit is None:
+ waitingcomments.extend(propunit.comments)
+ # FIXME the storage class should not be creating blank units
+ if pounit is "discard":
+ continue
+ if not appendedheader:
+ if propunit.isblank():
+ pounit = targetheader
+ else:
+ thetargetfile.addunit(targetheader)
+ appendedheader = True
+ if pounit is not None:
+ pounit.addnote("\n".join(waitingcomments).rstrip(), "developer", position="prepend")
+ waitingcomments = []
+ thetargetfile.addunit(pounit)
+ thetargetfile.removeduplicates(duplicatestyle)
+ return thetargetfile
+
+ def mergestore(self, origpropfile, translatedpropfile, personality="java", blankmsgstr=False, duplicatestyle="msgctxt"):
+ """converts two .properties files to a .po file..."""
+ self.personality = personality
+ thetargetfile = po.pofile()
+ if self.personality == "mozilla":
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit", x_accelerator_marker="&")
+ else:
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit")
+ targetheader.addnote("extracted from %s, %s" % (origpropfile.filename, translatedpropfile.filename), "developer")
+ translatedpropfile.makeindex()
+ # we try and merge the header po with any comments at the start of the properties file
+ appendedheader = False
+ waitingcomments = []
+ # loop through the original file, looking at units one by one
+ for origprop in origpropfile.units:
+ origpo = self.convertunit(origprop, "developer")
+ if origpo is None:
+ waitingcomments.extend(origprop.comments)
+ # FIXME the storage class should not be creating blank units
+ if origpo is "discard":
+ continue
+ # handle the header case specially...
+ if not appendedheader:
+ if origprop.isblank():
+ origpo = targetheader
+ else:
+ thetargetfile.addunit(targetheader)
+ appendedheader = True
+ # try and find a translation of the same name...
+ if origprop.name in translatedpropfile.locationindex:
+ translatedprop = translatedpropfile.locationindex[origprop.name]
+ # Need to check that this comment is not a copy of the developer comments
+ translatedpo = self.convertunit(translatedprop, "translator")
+ if translatedpo is "discard":
+ continue
+ else:
+ translatedpo = None
+ # if we have a valid po unit, get the translation and add it...
+ if origpo is not None:
+ if translatedpo is not None and not blankmsgstr:
+ origpo.target = translatedpo.source
+ origpo.addnote(u"".join(waitingcomments).rstrip(), "developer", position="prepend")
+ waitingcomments = []
+ thetargetfile.addunit(origpo)
+ elif translatedpo is not None:
+ print >> sys.stderr, "error converting original properties definition %s" % origprop.name
+ thetargetfile.removeduplicates(duplicatestyle)
+ return thetargetfile
+
+ def convertunit(self, propunit, commenttype):
+ """Converts a .properties unit to a .po unit. Returns None if empty
+ or not for translation."""
+ if propunit is None:
+ return None
+ # escape unicode
+ pounit = po.pounit(encoding="UTF-8")
+ if hasattr(propunit, "comments"):
+ for comment in propunit.comments:
+ if "DONT_TRANSLATE" in comment:
+ return "discard"
+ pounit.addnote(u"".join(propunit.getnotes()).rstrip(), commenttype)
+ # TODO: handle multiline msgid
+ if propunit.isblank():
+ return None
+ pounit.addlocation(propunit.name)
+ pounit.source = propunit.source
+ pounit.target = u""
+ return pounit
+
+def convertmozillaprop(inputfile, outputfile, templatefile, pot=False, duplicatestyle="msgctxt"):
+ """Mozilla specific convertor function"""
+ return convertprop(inputfile, outputfile, templatefile, personality="mozilla", pot=pot, duplicatestyle=duplicatestyle)
+
+def convertprop(inputfile, outputfile, templatefile, personality="java", pot=False, duplicatestyle="msgctxt"):
+ """reads in inputfile using properties, converts using prop2po, writes to outputfile"""
+ inputstore = properties.propfile(inputfile, personality)
+ convertor = prop2po()
+ if templatefile is None:
+ outputstore = convertor.convertstore(inputstore, personality, duplicatestyle=duplicatestyle)
+ else:
+ templatestore = properties.propfile(templatefile, personality)
+ outputstore = convertor.mergestore(templatestore, inputstore, personality, blankmsgstr=pot, duplicatestyle=duplicatestyle)
+ if outputstore.isempty():
+ return 0
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"properties": ("po", convertprop), ("properties", "properties"): ("po", convertprop)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__)
+ parser.add_option("", "--personality", dest="personality", default="java", type="choice",
+ choices=["java", "mozilla"],
+ help="set the input behaviour: java (default), mozilla", metavar="TYPE")
+ parser.add_duplicates_option()
+ parser.passthrough.append("pot")
+ parser.passthrough.append("personality")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/rc2po b/translate-toolkit-1.5.1/translate/convert/rc2po
new file mode 100755
index 0000000..119cfd8
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/rc2po
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2002, 2003, 2008 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a .rc file to a gettext .po localization file"""
+
+from translate.convert import rc2po
+
+if __name__ == '__main__':
+ rc2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/rc2po.py b/translate-toolkit-1.5.1/translate/convert/rc2po.py
new file mode 100644
index 0000000..3763270
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/rc2po.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2007-2009 Zuza Software Foundation
+#
+# This file is part of the Translate Toolkit.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+"""convert .rc files to Gettext PO localization files"""
+
+import sys
+from translate.storage import po
+from translate.storage import rc
+
+class rc2po:
+ """Convert a .rc file to a .po file for handling the translation."""
+ def __init__(self, charset=None):
+ self.charset = charset
+
+ def convert_store(self, input_store, duplicatestyle="msgctxt"):
+ """converts a .rc file to a .po file..."""
+ output_store = po.pofile()
+ output_header = output_store.makeheader(charset="UTF-8", encoding="8bit")
+ output_header.addnote("extracted from %s" % input_store.filename, "developer")
+ output_store.addunit(output_header)
+ for input_unit in input_store.units:
+ output_unit = self.convert_unit(input_unit, "developer")
+ if output_unit is not None:
+ output_store.addunit(output_unit)
+ output_store.removeduplicates(duplicatestyle)
+ return output_store
+
+ def merge_store(self, template_store, input_store, blankmsgstr=False, duplicatestyle="msgctxt"):
+ """converts two .rc files to a .po file..."""
+ output_store = po.pofile()
+ output_header = output_store.makeheader(charset="UTF-8", encoding="8bit")
+ output_header.addnote("extracted from %s, %s" % (template_store.filename, input_store.filename), "developer")
+ output_store.addunit(output_header)
+ input_store.makeindex()
+ for template_unit in template_store.units:
+ origpo = self.convert_unit(template_unit, "developer")
+ # try and find a translation of the same name...
+ template_unit_name = "".join(template_unit.getlocations())
+ if template_unit_name in input_store.locationindex:
+ translatedrc = input_store.locationindex[template_unit_name]
+ translatedpo = self.convert_unit(translatedrc, "translator")
+ else:
+ translatedpo = None
+ # if we have a valid po unit, get the translation and add it...
+ if origpo is not None:
+ if translatedpo is not None and not blankmsgstr:
+ origpo.target = translatedpo.source
+ output_store.addunit(origpo)
+ elif translatedpo is not None:
+ print >> sys.stderr, "error converting original rc definition %s" % origrc.name
+ output_store.removeduplicates(duplicatestyle)
+ return output_store
+
+ def convert_unit(self, input_unit, commenttype):
+ """Converts a .rc unit to a .po unit. Returns None if empty
+ or not for translation."""
+ if input_unit is None:
+ return None
+ # escape unicode
+ output_unit = po.pounit(encoding="UTF-8")
+ output_unit.addlocation("".join(input_unit.getlocations()))
+ output_unit.source = input_unit.source.decode(self.charset)
+ output_unit.target = ""
+ return output_unit
+
+def convertrc(input_file, output_file, template_file, pot=False, duplicatestyle="msgctxt", charset=None, lang=None, sublang=None):
+ """reads in input_file using rc, converts using rc2po, writes to output_file"""
+ input_store = rc.rcfile(input_file, lang, sublang)
+ convertor = rc2po(charset=charset)
+ if template_file is None:
+ output_store = convertor.convert_store(input_store, duplicatestyle=duplicatestyle)
+ else:
+ template_store = rc.rcfile(template_file, lang, sublang)
+ output_store = convertor.merge_store(template_store, input_store, blankmsgstr=pot, duplicatestyle=duplicatestyle)
+ if output_store.isempty():
+ return 0
+ output_file.write(str(output_store))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"rc": ("po", convertrc), ("rc", "rc"): ("po", convertrc),
+ "nls": ("po", convertrc), ("nls", "nls"): ("po", convertrc)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__)
+ DEFAULTCHARSET = "cp1252"
+ parser.add_option("", "--charset", dest="charset", default=DEFAULTCHARSET,
+ help="charset to use to decode the RC files (default: %s)" % DEFAULTCHARSET, metavar="CHARSET")
+ DEFAULTLANG = "LANG_ENGLISH"
+ parser.add_option("-l", "--lang", dest="lang", default=DEFAULTLANG,
+ help="LANG entry (default: %s)" % DEFAULTLANG, metavar="LANG")
+ DEFAULTSUBLANG = "SUBLANG_DEFAULT"
+ parser.add_option("", "--sublang", dest="sublang", default=DEFAULTSUBLANG,
+ help="SUBLANG entry (default: %s)" % DEFAULTSUBLANG, metavar="SUBLANG")
+ parser.add_duplicates_option()
+ parser.passthrough.append("pot")
+ parser.passthrough.append("charset")
+ parser.passthrough.append("lang")
+ parser.passthrough.append("sublang")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/sub2po b/translate-toolkit-1.5.1/translate/convert/sub2po
new file mode 100755
index 0000000..37cf865
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/sub2po
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a supported subtitle file to a Gettext PO localization file"""
+
+from translate.convert import sub2po
+
+if __name__ == '__main__':
+ sub2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/sub2po.py b/translate-toolkit-1.5.1/translate/convert/sub2po.py
new file mode 100644
index 0000000..0cef322
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/sub2po.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008-2009 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""convert subtitle files to Gettext PO localization files"""
+
+import sys
+from translate.storage import po
+from translate.storage import subtitles
+
+def convert_store(input_store, duplicatestyle="msgctxt"):
+ """converts a subtitle file to a .po file..."""
+ output_store = po.pofile()
+ output_header = output_store.makeheader(charset="UTF-8", encoding="8bit")
+ output_header.addnote("extracted from %s" % input_store.filename, "developer")
+ output_store.addunit(output_header)
+ for input_unit in input_store.units:
+ output_unit = convert_unit(input_unit, "developer")
+ if output_unit is not None:
+ output_store.addunit(output_unit)
+ output_store.removeduplicates(duplicatestyle)
+ return output_store
+
+def merge_store(template_store, input_store, blankmsgstr=False, duplicatestyle="msgctxt"):
+ """converts two subtitle files to a .po file..."""
+ output_store = po.pofile()
+ output_header = output_store.makeheader(charset="UTF-8", encoding="8bit")
+ output_header.addnote("extracted from %s, %s" % (template_store.filename, input_store.filename), "developer")
+ output_store.addunit(output_header)
+ input_store.makeindex()
+ for template_unit in template_store.units:
+ origpo = convert_unit(template_unit, "developer")
+ # try and find a translation of the same name...
+ template_unit_name = "".join(template_unit.getlocations())
+ if template_unit_name in input_store.locationindex:
+ translatedini = input_store.locationindex[template_unit_name]
+ translatedpo = convert_unit(translatedini, "translator")
+ else:
+ translatedpo = None
+ # if we have a valid po unit, get the translation and add it...
+ if origpo is not None:
+ if translatedpo is not None and not blankmsgstr:
+ origpo.target = translatedpo.source
+ output_store.addunit(origpo)
+ elif translatedpo is not None:
+ print >> sys.stderr, "error converting original subtitle definition %s" % origini.name
+ output_store.removeduplicates(duplicatestyle)
+ return output_store
+
+def convert_unit(input_unit, commenttype):
+ """Converts a subtitle unit to a .po unit. Returns None if empty
+ or not for translation."""
+ if input_unit is None:
+ return None
+ # escape unicode
+ output_unit = po.pounit(encoding="UTF-8")
+ output_unit.addlocation("".join(input_unit.getlocations()))
+ output_unit.addnote(input_unit.getnotes("developer"), "developer")
+ output_unit.source = input_unit.source
+ output_unit.target = ""
+ return output_unit
+
+def convertsub(input_file, output_file, template_file=None, pot=False, duplicatestyle="msgctxt"):
+ """Reads in L{input_file} using translate.subtitles, converts using L{sub2po}, writes to L{output_file}"""
+ input_store = subtitles.SubtitleFile(input_file)
+ if template_file is None:
+ output_store = convert_store(input_store, duplicatestyle=duplicatestyle)
+ else:
+ template_store = subtitles.SubtitleFile(template_file)
+ output_store = merge_store(template_store, input_store, blankmsgstr=pot, duplicatestyle=duplicatestyle)
+ if output_store.isempty():
+ return 0
+ output_file.write(str(output_store))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"srt": ("po", convertsub), ("srt", "srt"): ("po", convertsub)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__)
+ parser.add_duplicates_option()
+ parser.passthrough.append("pot")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/symb2po b/translate-toolkit-1.5.1/translate/convert/symb2po
new file mode 100755
index 0000000..066d766
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/symb2po
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of the Translate Toolkit.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+"""Convert a Symbian translation file to a gettext .po localization file."""
+
+from translate.convert import symb2po
+
+if __name__ == '__main__':
+ symb2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/symb2po.py b/translate-toolkit-1.5.1/translate/convert/symb2po.py
new file mode 100644
index 0000000..a965656
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/symb2po.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008-2009 Zuza Software Foundation
+#
+# This file is part of the Translate Toolkit.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+"""Convert Symbian localisation files to Gettext PO localization files."""
+
+from translate.storage import factory
+from translate.storage.pypo import extractpoline
+from translate.storage.symbian import *
+
+def read_header_items(ps):
+ match = read_while(ps, header_item_or_end_re.match, lambda match: match is None)
+ if match.groupdict()['end_comment'] is not None:
+ return {}
+
+ results = {}
+ while match:
+ match_chunks = match.groupdict()
+ ps.read_line()
+ results[match_chunks['key']] = match_chunks['value']
+ match = header_item_re.match(ps.current_line)
+
+ match = read_while(ps, identity, lambda line: not line.startswith('*/'))
+ ps.read_line()
+ return results
+
+def parse(ps):
+ header = read_header_items(ps)
+ units = []
+ try:
+ while True:
+ eat_whitespace(ps)
+ skip_no_translate(ps)
+ match = string_entry_re.match(ps.current_line)
+ if match is not None:
+ units.append((match.groupdict()['id'], extractpoline(match.groupdict()['str'])))
+ ps.read_line()
+ except StopIteration:
+ pass
+ return header, units
+
+def read_symbian(f):
+ lines = list(f)
+ charset = read_charset(lines)
+ return parse(ParseState(iter(lines), charset))
+
+def get_template_dict(template_file):
+ if template_file is not None:
+ template_header, template_units = read_symbian(template_file)
+ return template_header, dict(template_units)
+ else:
+ return {}, {}
+
+def build_output(units, template_header, template_dict):
+ output_store = factory.classes['po']()
+ ignore = set(['r_string_languagegroup_name'])
+ header_entries = {
+ 'Last-Translator': template_header.get('Author', ''),
+ 'Language-Team': template_dict.get('r_string_languagegroup_name', ''),
+ 'Content-Transfer-Encoding': '8bit',
+ 'Content-Type': 'text/plain; charset=UTF-8',
+ }
+ output_store.updateheader(add=True, **header_entries)
+ for id, source in units:
+ if id in ignore:
+ continue
+ unit = output_store.UnitClass(source)
+ unit.target = template_dict.get(id, '')
+ unit.addlocation(id)
+ output_store.addunit(unit)
+ return output_store
+
+def convert_symbian(input_file, output_file, template_file, pot=False, duplicatestyle="msgctxt"):
+ header, units = read_symbian(input_file)
+ template_header, template_dict = get_template_dict(template_file)
+ output_store = build_output(units, template_header, template_dict)
+
+ if output_store.isempty():
+ return 0
+ else:
+ output_file.write(str(output_store))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"r01": ("po", convert_symbian)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, usepots=True, description=__doc__)
+ parser.add_duplicates_option()
+ parser.passthrough.append("pot")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_accesskey.py b/translate-toolkit-1.5.1/translate/convert/test_accesskey.py
new file mode 100644
index 0000000..a632b73
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_accesskey.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Zuza Software Foundation
+#
+# This file is part of The Translate Toolkit.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""Test the various functions for combining and extracting accesskeys and
+labels"""
+
+from translate.convert import accesskey
+
+def test_get_label_and_accesskey():
+ """test that we can extract the label and accesskey components from an
+ accesskey+label string"""
+ assert accesskey.extract(u"&File") == (u"File", u"F")
+ assert accesskey.extract(u"~File", u"~") == (u"File", u"F")
+ assert accesskey.extract(u"~File", u"~") == (u"File", u"F")
+
+def test_ignore_entities():
+ """test that we don't get confused with entities and a & access key
+ marker"""
+ assert accesskey.extract(u"Set &browserName; as &Default") != (u"Set &browserName; as &Default", u"b")
+ assert accesskey.extract(u"Set &browserName; as &Default") == (u"Set &browserName; as Default", u"D")
+
+def test_alternate_accesskey_marker():
+ """check that we can identify the accesskey if the marker is different"""
+ assert accesskey.extract(u"~File", u"~") == (u"File", u"F")
+ assert accesskey.extract(u"&File", u"~") == (u"&File", u"")
+
+def test_unicode():
+ """test that we can do the same with unicode strings"""
+ assert accesskey.extract(u"Eḓiṱ") == (u"Eḓiṱ", u"")
+ assert accesskey.extract(u"E&ḓiṱ") == (u"Eḓiṱ", u"ḓ")
+ assert accesskey.extract(u"E_ḓiṱ", u"_") == (u"Eḓiṱ", u"ḓ")
+ label, akey = accesskey.extract(u"E&ḓiṱ")
+ assert label, akey == (u"Eḓiṱ", u"ḓ")
+ assert isinstance(label, unicode) and isinstance(akey, unicode)
+
+def test_empty_string():
+ """test that we can handle and empty label+accesskey string"""
+ assert accesskey.extract(u"") == (u"", u"")
+ assert accesskey.extract(u"", u"~") == (u"", u"")
+
+def test_combine_label_accesskey():
+ """test that we can combine accesskey and label to create a label+accesskey
+ string"""
+ assert accesskey.combine(u"File", u"F") == u"&File"
+ assert accesskey.combine(u"File", u"F", u"~") == u"~File"
+
+def test_uncombinable():
+ """test our behaviour when we cannot combine label and accesskey"""
+ assert accesskey.combine(u"File", u"D") is None
diff --git a/translate-toolkit-1.5.1/translate/convert/test_convert.py b/translate-toolkit-1.5.1/translate/convert/test_convert.py
new file mode 100644
index 0000000..31c1b66
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_convert.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import convert
+import os
+import sys
+from py import test
+try:
+ import psyco
+except Exception:
+ psyco = None
+
+class TestConvertCommand:
+ """Tests running actual commands on files"""
+ convertmodule = convert
+ defaultoptions = {"progress": "none"}
+ if psyco:
+ defaultoptions["psyco"] = "none"
+
+ def setup_method(self, method):
+ """creates a clean test directory for the given method"""
+ self.testdir = "%s_%s" % (self.__class__.__name__, method.__name__)
+ self.cleardir()
+ os.mkdir(self.testdir)
+ self.rundir = os.path.abspath(os.getcwd())
+
+ def teardown_method(self, method):
+ """removes the test directory for the given method"""
+ os.chdir(self.rundir)
+ self.cleardir()
+
+ def cleardir(self):
+ """removes the test directory"""
+ if os.path.exists(self.testdir):
+ for dirpath, subdirs, filenames in os.walk(self.testdir, topdown=False):
+ for name in filenames:
+ os.remove(os.path.join(dirpath, name))
+ for name in subdirs:
+ os.rmdir(os.path.join(dirpath, name))
+ if os.path.exists(self.testdir): os.rmdir(self.testdir)
+ assert not os.path.exists(self.testdir)
+
+ def run_command(self, *argv, **kwargs):
+ """runs the command via the main function, passing self.defaultoptions and keyword arguments as --long options and argv arguments straight"""
+ os.chdir(self.testdir)
+ argv = list(argv)
+ kwoptions = getattr(self, "defaultoptions", {}).copy()
+ kwoptions.update(kwargs)
+ for key, value in kwoptions.iteritems():
+ if value is True:
+ argv.append("--%s" % key)
+ else:
+ argv.append("--%s=%s" % (key, value))
+ try:
+ self.convertmodule.main(argv)
+ finally:
+ os.chdir(self.rundir)
+
+ def get_testfilename(self, filename):
+ """gets the path to the test file"""
+ return os.path.join(self.testdir, filename)
+
+ def open_testfile(self, filename, mode="r"):
+ """opens the given filename in the testdirectory in the given mode"""
+ filename = self.get_testfilename(filename)
+ if not mode.startswith("r"):
+ subdir = os.path.dirname(filename)
+ currentpath = ""
+ if not os.path.isdir(subdir):
+ for part in subdir.split(os.sep):
+ currentpath = os.path.join(currentpath, part)
+ if not os.path.isdir(currentpath):
+ os.mkdir(currentpath)
+ return open(filename, mode)
+
+ def create_testfile(self, filename, contents):
+ """creates the given file in the testdirectory with the given contents"""
+ testfile = self.open_testfile(filename, "w")
+ testfile.write(contents)
+
+ def read_testfile(self, filename):
+ """reads the given file in the testdirectory and returns the contents"""
+ testfile = open(self.get_testfilename(filename))
+ return testfile.read()
+
+ def help_check(self, options, option, last=False):
+ """check that a help string occurs and remove it"""
+ assert option in options
+ newoptions = []
+ for line in options.splitlines():
+ if option in line or not line.lstrip().startswith("-"):
+ continue
+ newoptions.append(line)
+ if last:
+ assert newoptions == []
+ return "\n".join(newoptions)
+
+ def test_help(self):
+ """tests getting help (returning the help_string so further tests can be done)"""
+ stdout = sys.stdout
+ helpfile = self.open_testfile("help.txt", "w")
+ sys.stdout = helpfile
+ try:
+ test.raises(SystemExit, self.run_command, help=True)
+ finally:
+ sys.stdout = stdout
+ helpfile.close()
+ help_string = self.read_testfile("help.txt")
+ print help_string
+ convertsummary = self.convertmodule.__doc__.split("\n")[0]
+ # the convertsummary might be wrapped. this will probably unwrap it
+ assert convertsummary in help_string.replace("\n", " ")
+ usageline = help_string[:help_string.find("\n")]
+ # Different versions of optparse might contain either upper or
+ # lowercase versions of 'Usage:' and 'Options:', so we need to take
+ # that into account
+ assert (usageline.startswith("Usage: ") or usageline.startswith("usage: ")) \
+ and "[--version] [-h|--help]" in usageline
+ options = help_string[help_string.find("ptions:\n"):]
+ options = options[options.find("\n")+1:]
+ options = self.help_check(options, "--progress=PROGRESS")
+ options = self.help_check(options, "--version")
+ options = self.help_check(options, "-h, --help")
+ options = self.help_check(options, "--manpage")
+ options = self.help_check(options, "--errorlevel=ERRORLEVEL")
+ if psyco:
+ options = self.help_check(options, "--psyco=MODE")
+ options = self.help_check(options, "-i INPUT, --input=INPUT")
+ options = self.help_check(options, "-x EXCLUDE, --exclude=EXCLUDE")
+ options = self.help_check(options, "-o OUTPUT, --output=OUTPUT")
+ return options
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_csv2po.py b/translate-toolkit-1.5.1/translate/convert/test_csv2po.py
new file mode 100644
index 0000000..dfa74f4
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_csv2po.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+
+from translate.convert import csv2po
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+from translate.storage import csvl10n
+
+class TestCSV2PO:
+ def csv2po(self, csvsource, template=None):
+ """helper that converts csv source to po source without requiring files"""
+ inputfile = wStringIO.StringIO(csvsource)
+ inputcsv = csvl10n.csvfile(inputfile)
+ if template:
+ templatefile = wStringIO.StringIO(template)
+ inputpot = po.pofile(templatefile)
+ else:
+ inputpot = None
+ convertor = csv2po.csv2po(templatepo=inputpot)
+ outputpo = convertor.convertstore(inputcsv)
+ return outputpo
+
+ def singleelement(self, storage):
+ """checks that the pofile contains a single non-header element, and returns it"""
+ print str(storage)
+ assert len(storage.units) == 1
+ return storage.units[0]
+
+ def test_simpleentity(self):
+ """checks that a simple csv entry definition converts properly to a po entry"""
+ csvheader = 'location,source,target\n'
+ csvsource = 'intl.charset.default,ISO-8859-1,UTF-16'
+ # Headerless
+ pofile = self.csv2po(csvsource)
+ pounit = self.singleelement(pofile)
+ # With header
+ pofile = self.csv2po(csvheader + csvsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.getlocations() == ['intl.charset.default']
+ assert pounit.source == "ISO-8859-1"
+ assert pounit.target == "UTF-16"
+
+ def test_simpleentity_with_template(self):
+ """checks that a simple csv entry definition converts properly to a po entry"""
+ csvsource = '''source,original,translation
+intl.charset.default,ISO-8859-1,UTF-16'''
+ potsource = '''#: intl.charset.default
+msgid "ISO-8859-1"
+msgstr ""
+'''
+ pofile = self.csv2po(csvsource, potsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.getlocations() == ['intl.charset.default']
+ assert pounit.source == "ISO-8859-1"
+ assert pounit.target == "UTF-16"
+
+ def test_newlines(self):
+ """tests multiline po entries"""
+ minicsv = r'''"Random comment
+with continuation","Original text","Langdradige teks
+wat lank aanhou"
+'''
+ pofile = self.csv2po(minicsv)
+ unit = self.singleelement(pofile)
+ assert unit.getlocations() == ['Random', 'comment', 'with', 'continuation']
+ assert unit.source == "Original text"
+ print unit.target
+ assert unit.target == "Langdradige teks\nwat lank aanhou"
+
+ def test_tabs(self):
+ """Test the escaping of tabs"""
+ minicsv = ',"First column\tSecond column","Twee kolomme gesky met \t"'
+ pofile = self.csv2po(minicsv)
+ unit = self.singleelement(pofile)
+ print unit.source
+ assert unit.source == "First column\tSecond column"
+ assert not pofile.findunit("First column\tSecond column").target == "Twee kolomme gesky met \\t"
+
+ def test_quotes(self):
+ """Test the escaping of quotes (and slash)"""
+ minicsv = r''',"Hello ""Everyone""","Good day ""All"""
+,"Use \"".","Gebruik \""."'''
+ print minicsv
+ csvfile = csvl10n.csvfile(wStringIO.StringIO(minicsv))
+ print str(csvfile)
+ pofile = self.csv2po(minicsv)
+ unit = pofile.units[0]
+ assert unit.source == 'Hello "Everyone"'
+ assert pofile.findunit('Hello "Everyone"').target == 'Good day "All"'
+ print str(pofile)
+ for unit in pofile.units:
+ print unit.source
+ print unit.target
+ print
+# assert pofile.findunit('Use \\".').target == 'Gebruik \\".'
+
+ def test_empties(self):
+ """Tests that things keep working with empty entries"""
+ minicsv = ',Source,'
+ pofile = self.csv2po(minicsv)
+ assert pofile.findunit("Source") is not None
+ assert pofile.findunit("Source").target == ""
+ assert len(pofile.units) == 1
+
+ def test_kdecomment(self):
+ """checks that we can merge into KDE comment entries"""
+ csvsource = '''location,source,target
+simple.c,Source,Target'''
+ potsource = r'''#: simple.c
+msgid "_: KDE comment\n"
+"Source"
+msgstr ""
+'''
+ pofile = self.csv2po(csvsource, potsource)
+ pounit = self.singleelement(pofile)
+ assert pounit._extract_msgidcomments() == 'KDE comment'
+ assert pounit.source == "Source"
+ assert pounit.target == "Target"
+
+class TestCSV2POCommand(test_convert.TestConvertCommand, TestCSV2PO):
+ """Tests running actual csv2po commands on files"""
+ convertmodule = csv2po
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "--charset=CHARSET")
+ options = self.help_check(options, "--columnorder=COLUMNORDER")
+ options = self.help_check(options, "--duplicates=DUPLICATESTYLE", last=True)
diff --git a/translate-toolkit-1.5.1/translate/convert/test_dtd2po.py b/translate-toolkit-1.5.1/translate/convert/test_dtd2po.py
new file mode 100644
index 0000000..9e13a14
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_dtd2po.py
@@ -0,0 +1,365 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import dtd2po
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+from translate.storage import dtd
+
+class TestDTD2PO:
+ def dtd2po(self, dtdsource, dtdtemplate=None):
+ """helper that converts dtd source to po source without requiring files"""
+ inputfile = wStringIO.StringIO(dtdsource)
+ inputdtd = dtd.dtdfile(inputfile)
+ convertor = dtd2po.dtd2po()
+ if dtdtemplate is None:
+ outputpo = convertor.convertstore(inputdtd)
+ else:
+ templatefile = wStringIO.StringIO(dtdtemplate)
+ templatedtd = dtd.dtdfile(templatefile)
+ outputpo = convertor.mergestore(templatedtd, inputdtd)
+ return outputpo
+
+ def convertdtd(self, dtdsource):
+ """call the convertdtd, return the outputfile"""
+ inputfile = wStringIO.StringIO(dtdsource)
+ outputfile = wStringIO.StringIO()
+ templatefile = None
+ assert dtd2po.convertdtd(inputfile, outputfile, templatefile)
+ return outputfile.getvalue()
+
+ def singleelement(self, pofile):
+ """checks that the pofile contains a single non-header element, and returns it"""
+ assert len(pofile.units) == 2
+ assert pofile.units[0].isheader()
+ print pofile.units[1]
+ return pofile.units[1]
+
+ def countelements(self, pofile):
+ """returns the number of non-header items"""
+ if pofile.units[0].isheader():
+ return len(pofile.units) - 1
+ else:
+ return len(pofile.units)
+
+ def test_simpleentity(self):
+ """checks that a simple dtd entity definition converts properly to a po entry"""
+ dtdsource = '<!ENTITY test.me "bananas for sale">\n'
+ pofile = self.dtd2po(dtdsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "bananas for sale"
+ assert pounit.target == ""
+ # Now with a template language
+ dtdtemplate = '<!ENTITY test.me "bananas for sale">\n'
+ dtdtranslated = '<!ENTITY test.me "piesangs te koop">\n'
+ pofile = self.dtd2po(dtdtranslated, dtdtemplate)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "bananas for sale"
+ assert pounit.target == "piesangs te koop"
+
+ def test_convertdtd(self):
+ """checks that the convertdtd function is working"""
+ dtdsource = '<!ENTITY saveas.label "Save As...">\n'
+ posource = self.convertdtd(dtdsource)
+ pofile = po.pofile(wStringIO.StringIO(posource))
+ unit = self.singleelement(pofile)
+ assert unit.source == "Save As..."
+ assert unit.target == ""
+
+ def test_apos(self):
+ """apostrophe should not break a single-quoted entity definition, bug 69"""
+ dtdsource = "<!ENTITY test.me 'bananas &apos; for sale'>\n"
+ pofile = self.dtd2po(dtdsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "bananas ' for sale"
+
+ def test_quotes(self):
+ """quotes should be handled in a single-quoted entity definition"""
+ dtdsource = """<!ENTITY test.metoo '"Bananas" for sale'>\n"""
+ pofile = self.dtd2po(dtdsource)
+ pounit = self.singleelement(pofile)
+ print str(pounit)
+ assert pounit.source == '"Bananas" for sale'
+
+ def test_emptyentity(self):
+ """checks that empty entity definitions survive into po file, bug 15"""
+ dtdsource = '<!ENTITY credit.translation "">\n'
+ pofile = self.dtd2po(dtdsource)
+ pounit = self.singleelement(pofile)
+ assert "credit.translation" in str(pounit)
+ assert 'msgctxt "credit.translation"' in str(pounit)
+
+ def test_emptyentity_translated(self):
+ """checks that if we translate an empty entity it makes it into the PO, bug 101"""
+ dtdtemplate = '<!ENTITY credit.translation "">\n'
+ dtdsource = '<!ENTITY credit.translation "Translators Names">\n'
+ pofile = self.dtd2po(dtdsource, dtdtemplate)
+ unit = self.singleelement(pofile)
+ print unit
+ assert "credit.translation" in str(unit)
+ # We don't want this to simply be seen as a header:
+ assert len(unit.getid()) != 0
+ assert unit.target == "Translators Names"
+
+ def test_localisaton_note_simple(self):
+ """test the simple localisation more becomes a #. comment"""
+ dtdsource = '''<!-- LOCALIZATION NOTE (alwaysCheckDefault.height):
+ There's some sort of bug which makes wrapping checkboxes not properly reflow,
+ causing the bottom border of the groupbox to be cut off; set this
+ appropriately if your localization causes this checkbox to wrap.
+-->
+<!ENTITY alwaysCheckDefault.height "3em">
+'''
+ pofile = self.dtd2po(dtdsource)
+ posource = str(pofile)
+ print posource
+ assert posource.count('#.') == 5 # 1 Header extracted from, 3 comment lines, 1 autoinserted comment
+
+ def test_localisation_note_merge(self):
+ """test that LOCALIZATION NOTES are added properly as #. comments and disambiguated with msgctxt entries"""
+ dtdtemplate = '<!--LOCALIZATION NOTE (%s): Some note -->\n' + \
+ '<!ENTITY %s "Source text">\n'
+ dtdsource = dtdtemplate % ("note1.label", "note1.label") + dtdtemplate % ("note2.label", "note2.label")
+ pofile = self.dtd2po(dtdsource)
+ posource = str(pofile.units[1]) + str(pofile.units[2])
+ print posource
+ assert posource.count('#.') == 2
+ assert posource.count('msgctxt') == 2
+
+ def test_donttranslate_simple(self):
+ """check that we handle DONT_TRANSLATE messages properly"""
+ dtdsource = '''<!-- LOCALIZATION NOTE (region.Altitude): DONT_TRANSLATE -->
+<!ENTITY region.Altitude "Very High">'''
+ pofile = self.dtd2po(dtdsource)
+ assert self.countelements(pofile) == 0
+ dtdsource = '''<!-- LOCALIZATION NOTE (exampleOpenTag.label): DONT_TRANSLATE: they are text for HTML tagnames: "<i>" and "</i>" -->
+<!ENTITY exampleOpenTag.label "&lt;i&gt;">'''
+ pofile = self.dtd2po(dtdsource)
+ assert self.countelements(pofile) == 0
+ dtdsource = '''<!-- LOCALIZATION NOTE (imapAdvanced.label): Do not translate "IMAP" -->
+<!ENTITY imapAdvanced.label "Advanced IMAP Server Settings">'''
+ pofile = self.dtd2po(dtdsource)
+ assert self.countelements(pofile) == 1
+
+ def test_donttranslate_label(self):
+ """test strangeness when label entity is marked DONT_TRANSLATE and accesskey is not, bug 30"""
+ dtdsource = '<!--LOCALIZATION NOTE (editorCheck.label): DONT_TRANSLATE -->\n' + \
+ '<!ENTITY editorCheck.label "Composer">\n<!ENTITY editorCheck.accesskey "c">\n'
+ pofile = self.dtd2po(dtdsource)
+ posource = str(pofile)
+ # we need to decided what we're going to do here - see the comments in bug 30
+ # this tests the current implementation which is that the DONT_TRANSLATE string is removed, but the other remains
+ assert 'editorCheck.label' not in posource
+ assert 'editorCheck.accesskey' in posource
+
+ def test_donttranslate_onlyentity(self):
+ """if the entity is itself just another entity then it shouldn't appear in the output PO file"""
+ dtdsource = '''<!-- LOCALIZATION NOTE (mainWindow.title): DONT_TRANSLATE -->
+<!ENTITY mainWindow.title "&brandFullName;">'''
+ pofile = self.dtd2po(dtdsource)
+ assert self.countelements(pofile) == 0
+
+ def test_donttranslate_commentedout(self):
+ """check that we don't process messages in <!-- comments -->: bug 102"""
+ dtdsource = '''<!-- commenting out until bug 38906 is fixed
+<!ENTITY messagesHeader.label "Messages"> -->'''
+ pofile = self.dtd2po(dtdsource)
+ assert self.countelements(pofile) == 0
+
+ def test_spaces_at_start_of_dtd_lines(self):
+ """test that pretty print spaces at the start of subsequent DTD element lines are removed from the PO file, bug 79"""
+ # Space at the end of the line
+ dtdsource = '<!ENTITY noupdatesfound.intro "First line then \n' + \
+ ' next lines.">\n'
+ pofile = self.dtd2po(dtdsource)
+ pounit = self.singleelement(pofile)
+ # We still need to decide how we handle line line breaks in the DTD entities. It seems that we should actually
+ # drop the line break but this has not been implemented yet.
+ assert pounit.source == "First line then \nnext lines."
+ # No space at the end of the line
+ dtdsource = '<!ENTITY noupdatesfound.intro "First line then\n' + \
+ ' next lines.">\n'
+ pofile = self.dtd2po(dtdsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "First line then \nnext lines."
+
+ def test_accesskeys_folding(self):
+ """test that we fold accesskeys into message strings"""
+ dtdsource_template = '<!ENTITY fileSaveAs.%s "Save As...">\n<!ENTITY fileSaveAs.%s "S">\n'
+ lang_template = '<!ENTITY fileSaveAs.%s "Gcina ka...">\n<!ENTITY fileSaveAs.%s "G">\n'
+ for label in ("label", "title"):
+ for accesskey in ("accesskey", "accessKey", "akey"):
+ pofile = self.dtd2po(dtdsource_template % (label, accesskey))
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "&Save As..."
+ # Test with template (bug 155)
+ pofile = self.dtd2po(lang_template % (label, accesskey), dtdsource_template % (label, accesskey))
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "&Save As..."
+ assert pounit.target == "&Gcina ka..."
+
+ def test_accesskeys_mismatch(self):
+ """check that we can handle accesskeys that don't match and thus can't be folded into the .label entry"""
+ dtdsource = '<!ENTITY fileSave.label "Save">\n' + \
+ '<!ENTITY fileSave.accesskey "z">\n'
+ pofile = self.dtd2po(dtdsource)
+ assert self.countelements(pofile) == 2
+
+ def test_carriage_return_in_multiline_dtd(self):
+ """test that we create nice PO files when we find a \r\n in a multiline DTD element"""
+ dtdsource = '<!ENTITY noupdatesfound.intro "First line then \r\n' + \
+ ' next lines.">\n'
+ pofile = self.dtd2po(dtdsource)
+ unit = self.singleelement(pofile)
+ assert unit.source == "First line then \nnext lines."
+
+ def test_multiline_with_blankline(self):
+ """test that we can process a multiline entity that has a blank line in it, bug 331"""
+ dtdsource = '''
+<!ENTITY multiline.text "
+Some text
+
+Some other text
+">'''
+ pofile = self.dtd2po(dtdsource)
+ unit = self.singleelement(pofile)
+ assert unit.source == "Some text \n \nSome other text"
+
+ def test_mulitline_closing_quotes(self):
+ """test that we support various styles and spaces after closing quotes on multiline entities"""
+ dtdsource = '''
+<!ENTITY pref.plural '<span>opsies</span><span
+ class="noWin">preferences</span>' >
+'''
+ pofile = self.dtd2po(dtdsource)
+ unit = self.singleelement(pofile)
+ assert unit.source == '<span>opsies</span><span \nclass="noWin">preferences</span>'
+
+ def test_preserving_spaces(self):
+ """test that we preserve space that appear at the start of the first line of a DTD entity"""
+ # Space before first character
+ dtdsource = '<!ENTITY mainWindow.titlemodifiermenuseparator " - ">'
+ pofile = self.dtd2po(dtdsource)
+ unit = self.singleelement(pofile)
+ assert unit.source == " - "
+ # Double line and spaces
+ dtdsource = '<!ENTITY mainWindow.titlemodifiermenuseparator " - with a newline\n and more text">'
+ pofile = self.dtd2po(dtdsource)
+ unit = self.singleelement(pofile)
+ print repr(unit.source)
+ assert unit.source == " - with a newline \nand more text"
+
+ def test_escaping_newline_tabs(self):
+ """test that we handle all kinds of newline permutations"""
+ dtdsource = '<!ENTITY noupdatesfound.intro "A hard coded newline.\\nAnd tab\\t and a \\r carriage return.">\n'
+ converter = dtd2po.dtd2po()
+ thedtd = dtd.dtdunit()
+ thedtd.parse(dtdsource)
+ thepo = po.pounit()
+ converter.convertstrings(thedtd, thepo)
+ print thedtd
+ print thepo.source
+ # \n in a dtd should also appear as \n in the PO file
+ assert thepo.source == r"A hard coded newline.\nAnd tab\t and a \r carriage return."
+
+ def test_abandoned_accelerator(self):
+ """test that when a language DTD has an accelerator but the template DTD does not that we abandon the accelerator"""
+ dtdtemplate = '<!ENTITY test.label "Test">\n'
+ dtdlanguage = '<!ENTITY test.label "Toets">\n<!ENTITY test.accesskey "T">\n'
+ pofile = self.dtd2po(dtdlanguage, dtdtemplate)
+ unit = self.singleelement(pofile)
+ assert unit.source == "Test"
+ assert unit.target == "Toets"
+
+ def test_unassociable_accelerator(self):
+ """test to see that we can handle accelerator keys that cannot be associated correctly"""
+ dtdsource = '<!ENTITY managecerts.button "Manage Certificates...">\n<!ENTITY managecerts.accesskey "M">'
+ pofile = self.dtd2po(dtdsource)
+ assert pofile.units[1].source == "Manage Certificates..."
+ assert pofile.units[2].source == "M"
+ pofile = self.dtd2po(dtdsource, dtdsource)
+ assert pofile.units[1].target == "Manage Certificates..."
+ assert pofile.units[2].target == "M"
+
+ def test_changed_labels_and_accelerators(self):
+ """test to ensure that when the template changes an entity name we can still manage the accelerators"""
+ dtdtemplate = '''<!ENTITY managecerts.caption "Manage Certificates">
+<!ENTITY managecerts.text "Use the Certificate Manager to manage your personal certificates, as well as those of other people and certificate authorities.">
+<!ENTITY managecerts.button "Manage Certificates...">
+<!ENTITY managecerts.accesskey "M">'''
+ dtdlanguage = '''<!ENTITY managecerts.label "ﺇﺩﺍﺭﺓ ﺎﻠﺸﻫﺍﺩﺎﺗ">
+<!ENTITY managecerts.text "ﺎﺴﺘﺧﺪﻣ ﻡﺪﻳﺭ ﺎﻠﺸﻫﺍﺩﺎﺗ ﻹﺩﺍﺭﺓ ﺶﻫﺍﺩﺎﺘﻛ ﺎﻠﺸﺨﺼﻳﺓ، ﺏﺍﻺﺿﺎﻓﺓ ﻞﺘﻠﻛ ﺎﻠﺧﺎﺻﺓ ﺏﺍﻶﺧﺮﻴﻧ ﻭ ﺲﻠﻃﺎﺗ ﺎﻠﺸﻫﺍﺩﺎﺗ.">
+<!ENTITY managecerts.button "ﺇﺩﺍﺭﺓ ﺎﻠﺸﻫﺍﺩﺎﺗ...">
+<!ENTITY managecerts.accesskey "ﺩ">'''
+ pofile = self.dtd2po(dtdlanguage, dtdtemplate)
+ print pofile
+ assert pofile.units[3].source == "Manage Certificates..."
+ assert pofile.units[3].target == u"ﺇﺩﺍﺭﺓ ﺎﻠﺸﻫﺍﺩﺎﺗ..."
+ assert pofile.units[4].source == "M"
+ assert pofile.units[4].target == u"ﺩ"
+
+ def wtest_accelerator_keys_not_in_sentence(self):
+ """tests to ensure that we can manage accelerator keys that are not part of the transated sentence eg in Chinese"""
+ dtdtemplate = '''<!ENTITY useAutoScroll.label "Use autoscrolling">
+<!ENTITY useAutoScroll.accesskey "a">'''
+ dtdlanguage = '''<!ENTITY useAutoScroll.label "使用自動捲動(Autoscrolling)">
+<!ENTITY useAutoScroll.accesskey "a">'''
+ pofile = self.dtd2po(dtdlanguage, dtdtemplate)
+ print pofile
+ assert pofile.units[1].target == "使用自動捲動(&Autoscrolling)"
+ # We assume that accesskeys with no associated key should be done as follows "XXXX (&A)"
+ # TODO - check that we can unfold this from PO -> DTD
+ dtdlanguage = '''<!ENTITY useAutoScroll.label "使用自動捲動">
+<!ENTITY useAutoScroll.accesskey "a">'''
+ pofile = self.dtd2po(dtdlanguage, dtdtemplate)
+ print pofile
+ assert pofile.units[1].target == "使用自動捲動 (&A)"
+
+ def test_exclude_entity_includes(self):
+ """test that we don't turn an include into a translatable string"""
+ dtdsource = '<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">'
+ pofile = self.dtd2po(dtdsource)
+ assert self.countelements(pofile) == 0
+
+ def test_linewraps(self):
+ """check that redundant line wraps are removed from the po file"""
+ dtdsource = '''<!ENTITY generic.longDesc "
+<p>Test me.</p>
+">'''
+ pofile = self.dtd2po(dtdsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "<p>Test me.</p>"
+
+ def test_merging_with_new_untranslated(self):
+ """test that when we merge in new untranslated strings with existing translations we manage the encodings properly"""
+ # This should probably be in test_po.py but was easier to do here
+ dtdtemplate = '''<!ENTITY unreadFolders.label "Unread">\n<!ENTITY viewPickerUnread.label "Unread">\n<!ENTITY unreadColumn.label "Unread">'''
+ dtdlanguage = '''<!ENTITY viewPickerUnread.label "Непрочетени">\n<!ENTITY unreadFolders.label "Непрочетени">'''
+ pofile = self.dtd2po(dtdlanguage, dtdtemplate)
+ print pofile
+ assert pofile.units[1].source == "Unread"
+
+ def test_merge_without_template(self):
+ """test that we we manage the case where we merge and their is no template file"""
+ # If we supply a template file we should fail if the template file does not exist or is blank. We should
+ # not put the translation in as the source.
+ # TODO: this test fails, since line 16 checks for "not dtdtemplate"
+ # instead of checking for "dtdtemplate is None". What is correct?
+ dtdtemplate = ''
+ dtdsource = '<!ENTITY no.template "Target">'
+ pofile = self.dtd2po(dtdsource, dtdtemplate)
+ print pofile
+ assert self.countelements(pofile) == 0
+
+class TestDTD2POCommand(test_convert.TestConvertCommand, TestDTD2PO):
+ """Tests running actual dtd2po commands on files"""
+ convertmodule = dtd2po
+ defaultoptions = {"progress": "none"}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-P, --pot")
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "--duplicates=DUPLICATESTYLE", last=True)
diff --git a/translate-toolkit-1.5.1/translate/convert/test_html2po.py b/translate-toolkit-1.5.1/translate/convert/test_html2po.py
new file mode 100644
index 0000000..a868e63
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_html2po.py
@@ -0,0 +1,430 @@
+#!/usr/bin/env python
+
+from translate.convert import html2po
+from translate.convert import po2html
+from translate.convert import test_convert
+from translate.misc import wStringIO
+
+class TestHTML2PO:
+ def html2po(self, markup, includeuntagged=False, duplicatestyle="msgctxt", keepcomments=False):
+ """Helper to convert html to po without a file."""
+ inputfile = wStringIO.StringIO(markup)
+ convertor = html2po.html2po()
+ outputpo = convertor.convertfile(inputfile, "test", False, includeuntagged, duplicatestyle, keepcomments)
+ return outputpo
+
+ def po2html(self, posource, htmltemplate):
+ """Helper to convert po to html without a file."""
+ inputfile = wStringIO.StringIO(posource)
+ outputfile = wStringIO.StringIO()
+ templatefile = wStringIO.StringIO(htmltemplate)
+ assert po2html.converthtml(inputfile, outputfile, templatefile)
+ return outputfile.getvalue()
+
+ def countunits(self, pofile, expected):
+ """helper to check that we got the expected number of messages"""
+ actual = len(pofile.units)
+ if actual > 0:
+ if pofile.units[0].isheader():
+ actual = actual - 1
+ print pofile
+ assert actual == expected
+
+ def compareunit(self, pofile, unitnumber, expected):
+ """helper to validate a PO message"""
+ if not pofile.units[0].isheader():
+ unitnumber = unitnumber - 1
+ print 'unit source: ' + pofile.units[unitnumber].source.encode('utf-8') + '|'
+ print 'expected: ' + expected.encode('utf-8') + '|'
+ assert unicode(pofile.units[unitnumber].source) == unicode(expected)
+
+ def check_single(self, markup, itemtext):
+ """checks that converting this markup produces a single element with value itemtext"""
+ pofile = self.html2po(markup)
+ self.countunits(pofile, 1)
+ self.compareunit(pofile, 1, itemtext)
+
+ def check_null(self, markup):
+ """checks that converting this markup produces no elements"""
+ pofile = self.html2po(markup)
+ self.countunits(pofile, 0)
+
+ def check_phpsnippet(self, php):
+ """Given a snippet of php, put it into an HTML shell and see
+ if the results are as expected"""
+ self.check_single('<html><head></head><body><p><a href="'+php+'/site.html">Body text</a></p></body></html>', "Body text")
+ self.check_single('<html><head></head><body><p>More things in <a href="'+php+'/site.html">Body text</a></p></body></html>', 'More things in <a href="'+php+'/site.html">Body text</a>')
+ self.check_null('<html><head></head><body><p>'+php+'</p></body></html>')
+
+ def test_htmllang(self):
+ """test to ensure that we no longer use the lang attribure"""
+ markup = '''<html lang="en"><head><title>My title</title></head><body></body></html>'''
+ pofile = self.html2po(markup)
+ self.countunits(pofile, 1)
+ # Check that the first item is the <title> not <head>
+ self.compareunit(pofile, 1, "My title")
+
+ def test_title(self):
+ """test that we can extract the <title> tag"""
+ self.check_single("<html><head><title>My title</title></head><body></body></html>", "My title")
+
+ def test_title_with_linebreak(self):
+ """Test a linebreak in the <title> tag"""
+ htmltext = '''<html>
+<head>
+ <title>My
+title</title>
+</head>
+<body>
+</body>
+</html>
+'''
+ self.check_single(htmltext, "My title")
+
+ def test_meta(self):
+ """Test that we can extract certain <meta> info from <head>."""
+ self.check_single('''<html><head><meta name="keywords" content="these are keywords"></head><body></body></html>''', "these are keywords")
+
+ def test_tag_p(self):
+ """test that we can extract the <p> tag"""
+ self.check_single("<html><head></head><body><p>A paragraph.</p></body></html>", "A paragraph.")
+ markup = "<p>First line.<br>Second line.</p>"
+ pofile = self.html2po(markup)
+ self.compareunit(pofile, 1, "First line.<br>Second line.")
+
+ def test_tag_p_with_linebreak(self):
+ """Test newlines within the <p> tag."""
+ htmltext = '''<html>
+<head>
+</head>
+<body>
+<p>
+A paragraph is a section in a piece of writing, usually highlighting a
+particular point or topic. It always begins on a new line and usually
+with indentation, and it consists of at least one sentence.
+</p>
+</body>
+</html>
+'''
+ self.check_single(htmltext, "A paragraph is a section in a piece of writing, usually highlighting a particular point or topic. It always begins on a new line and usually with indentation, and it consists of at least one sentence.")
+ markup = "<p>First\nline.<br>Second\nline.</p>"
+ pofile = self.html2po(markup)
+ self.compareunit(pofile, 1, "First line.<br>Second line.")
+
+ def test_tag_div(self):
+ """test that we can extract the <div> tag"""
+ self.check_single("<html><head></head><body><div>A paragraph.</div></body></html>", "A paragraph.")
+ markup = "<div>First line.<br>Second line.</div>"
+ pofile = self.html2po(markup)
+ self.compareunit(pofile, 1, "First line.<br>Second line.")
+
+ def test_tag_div_with_linebreaks(self):
+ """Test linebreaks within a <div> tag."""
+ htmltext = '''<html>
+<head>
+</head>
+<body>
+<div>
+A paragraph is a section in a piece of writing, usually highlighting a
+particular point or topic. It always begins on a new line and usually
+with indentation, and it consists of at least one sentence.
+</div>
+</body>
+</html>
+'''
+ self.check_single(htmltext, "A paragraph is a section in a piece of writing, usually highlighting a particular point or topic. It always begins on a new line and usually with indentation, and it consists of at least one sentence.")
+ markup = "<div>First\nline.<br>Second\nline.</div>"
+ pofile = self.html2po(markup)
+ self.compareunit(pofile, 1, "First line.<br>Second line.")
+
+ def test_tag_a(self):
+ """test that we can extract the <a> tag"""
+ self.check_single('<html><head></head><body><p>A paragraph with <a href="http://translate.org.za/">hyperlink</a>.</p></body></html>', 'A paragraph with <a href="http://translate.org.za/">hyperlink</a>.')
+
+ def test_tag_a_with_linebreak(self):
+ """Test that we can extract the <a> tag with newlines in it."""
+ htmltext = '''<html>
+<head>
+</head>
+<body>
+<p>A
+paragraph
+with <a
+href="http://translate.org.za/">hyperlink</a>
+and
+newlines.</p></body></html>
+'''
+ self.check_single(htmltext, 'A paragraph with <a href="http://translate.org.za/">hyperlink</a> and newlines.')
+
+ def test_tag_img(self):
+ """Test that we can extract the alt attribute from the <img> tag."""
+ self.check_single('''<html><head></head><body><img src="picture.png" alt="A picture"></body></html>''', "A picture")
+
+ def test_img_empty(self):
+ """Test that we can extract the alt attribute from the <img> tag."""
+ htmlsource = '''<html><head></head><body><img src="images/topbar.jpg" width="750" height="80"></body></html>'''
+ self.check_null(htmlsource)
+
+ def test_tag_table_summary(self):
+ """Test that we can extract the summary attribute."""
+ self.check_single('''<html><head></head><body><table summary="Table summary"></table></body></html>''', "Table summary")
+
+ def test_table_simple(self):
+ """Test that we can fully extract a simple table."""
+ markup = '''<html><head></head><body><table><tr><th>Heading One</th><th>Heading Two</th><tr><td>One</td><td>Two</td></tr></table></body></html>'''
+ pofile = self.html2po(markup)
+ self.countunits(pofile, 4)
+ self.compareunit(pofile, 1, "Heading One")
+ self.compareunit(pofile, 2, "Heading Two")
+ self.compareunit(pofile, 3, "One")
+ self.compareunit(pofile, 4, "Two")
+
+ def test_table_complex(self):
+ markup = '''<table summary="This is the summary"><caption>A caption</caption><thead><tr><th abbr="Head 1">Heading One</th><th>Heading Two</th></thead><tfoot><tr><td>Foot One</td><td>Foot Two</td></tr></tfoot><tbody><tr><td>One</td><td>Two</td></tr></tbody></table>'''
+ pofile = self.html2po(markup)
+ self.countunits(pofile, 9)
+ self.compareunit(pofile, 1, "This is the summary")
+ self.compareunit(pofile, 2, "A caption")
+ self.compareunit(pofile, 3, "Head 1")
+ self.compareunit(pofile, 4, "Heading One")
+ self.compareunit(pofile, 5, "Heading Two")
+ self.compareunit(pofile, 6, "Foot One")
+ self.compareunit(pofile, 7, "Foot Two")
+ self.compareunit(pofile, 8, "One")
+ self.compareunit(pofile, 9, "Two")
+
+ def test_table_empty(self):
+ """Test that we ignore tables that are empty.
+
+ A table is deemed empty if it has no translatable content.
+ """
+
+ self.check_null('''<html><head></head><body><table><tr><td><img src="bob.png"></td></tr></table></body></html>''')
+ self.check_null('''<html><head></head><body><table><tr><td>&nbsp;</td></tr></table></body></html>''')
+ self.check_null('''<html><head></head><body><table><tr><td><strong></strong></td></tr></table></body></html>''')
+
+ def test_address(self):
+ """Test to see if the address element is extracted"""
+ self.check_single("<body><address>My address</address></body>", "My address")
+
+ def test_headings(self):
+ """Test to see if the h* elements are extracted"""
+ markup = "<html><head></head><body><h1>Heading One</h1><h2>Heading Two</h2><h3>Heading Three</h3><h4>Heading Four</h4><h5>Heading Five</h5><h6>Heading Six</h6></body></html>"
+ pofile = self.html2po(markup)
+ self.countunits(pofile, 6)
+ self.compareunit(pofile, 1, "Heading One")
+ self.compareunit(pofile, 2, "Heading Two")
+ self.compareunit(pofile, 3, "Heading Three")
+ self.compareunit(pofile, 4, "Heading Four")
+ self.compareunit(pofile, 5, "Heading Five")
+ self.compareunit(pofile, 6, "Heading Six")
+
+ def test_headings_with_linebreaks(self):
+ """Test to see if h* elements with newlines can be extracted"""
+ markup = "<html><head></head><body><h1>Heading\nOne</h1><h2>Heading\nTwo</h2><h3>Heading\nThree</h3><h4>Heading\nFour</h4><h5>Heading\nFive</h5><h6>Heading\nSix</h6></body></html>"
+ pofile = self.html2po(markup)
+ self.countunits(pofile, 6)
+ self.compareunit(pofile, 1, "Heading One")
+ self.compareunit(pofile, 2, "Heading Two")
+ self.compareunit(pofile, 3, "Heading Three")
+ self.compareunit(pofile, 4, "Heading Four")
+ self.compareunit(pofile, 5, "Heading Five")
+ self.compareunit(pofile, 6, "Heading Six")
+
+ def test_dt(self):
+ """Test to see if the definition list title (dt) element is extracted"""
+ self.check_single("<html><head></head><body><dl><dt>Definition List Item Title</dt></dl></body></html>", "Definition List Item Title")
+
+ def test_dd(self):
+ """Test to see if the definition list description (dd) element is extracted"""
+ self.check_single("<html><head></head><body><dl><dd>Definition List Item Description</dd></dl></body></html>", "Definition List Item Description")
+
+ def test_span(self):
+ """test to check that we don't double extract a span item"""
+ self.check_single("<html><head></head><body><p>You are a <span>Spanish</span> sentence.</p></body></html>", "You are a <span>Spanish</span> sentence.")
+
+ def test_ul(self):
+ """Test to see if the list item <li> is exracted"""
+ markup = "<html><head></head><body><ul><li>Unordered One</li><li>Unordered Two</li></ul><ol><li>Ordered One</li><li>Ordered Two</li></ol></body></html>"
+ pofile = self.html2po(markup)
+ self.countunits(pofile, 4)
+ self.compareunit(pofile, 1, "Unordered One")
+ self.compareunit(pofile, 2, "Unordered Two")
+ self.compareunit(pofile, 3, "Ordered One")
+ self.compareunit(pofile, 4, "Ordered Two")
+
+ def test_duplicates(self):
+ """check that we use the default style of msgctxt to disambiguate duplicate messages"""
+ markup = "<html><head></head><body><p>Duplicate</p><p>Duplicate</p></body></html>"
+ pofile = self.html2po(markup)
+ self.countunits(pofile, 2)
+ # FIXME change this so that we check that the msgctxt is correctly added
+ self.compareunit(pofile, 1, "Duplicate")
+ self.compareunit(pofile, 2, "Duplicate")
+
+ def wtest_multiline_reflow(self):
+ """check that we reflow multiline content to make it more readable for translators"""
+ self.check_single('''<td valign="middle" width="96%"><font class="headingwhite">South
+ Africa</font></td>''', '''<font class="headingwhite">South Africa</font>''')
+
+ def wtest_nested_tags(self):
+ """check that we can extract items within nested tags"""
+ markup = "<div><p>Extract this</p>And this</div>"
+ pofile = self.html2po(markup)
+ self.countunits(pofile, 2)
+ self.compareunit(pofile, 1, "Extract this")
+ self.compareunit(pofile, 2, "And this")
+
+ def test_carriage_return(self):
+ """Remove carriage returns from files in dos format."""
+ htmlsource = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r
+<html><!-- InstanceBegin template="/Templates/masterpage.dwt" codeOutsideHTMLIsLocked="false" -->\r
+<head>\r
+<!-- InstanceBeginEditable name="doctitle" -->\r
+<link href="fmfi.css" rel="stylesheet" type="text/css">\r
+</head>\r
+\r
+<body>\r
+<p>The rapid expansion of telecommunications infrastructure in recent\r
+years has helped to bridge the digital divide to a limited extent.</p> \r
+</body>\r
+<!-- InstanceEnd --></html>\r
+'''
+
+ self.check_single(htmlsource, 'The rapid expansion of telecommunications infrastructure in recent years has helped to bridge the digital divide to a limited extent.')
+
+ def test_encoding_latin1(self):
+ """Convert HTML input in iso-8859-1 correctly to unicode."""
+ htmlsource = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><!-- InstanceBegin template="/Templates/masterpage.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>FMFI - South Africa - CSIR Openphone - Overview</title>
+<!-- InstanceEndEditable -->
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="keywords" content="fmfi, first mile, first inch, wireless, rural development, access devices, mobile devices, wifi, connectivity, rural connectivty, ict, low cost, cheap, digital divide, csir, idrc, community">
+
+<!-- InstanceBeginEditable name="head" -->
+<!-- InstanceEndEditable -->
+<link href="../../../fmfi.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<p>We aim to please \x96 will you aim too, please?</p>
+<p>South Africa\x92s language diversity can be challenging.</p>
+</body>
+</html>
+'''
+ pofile = self.html2po(htmlsource)
+
+ self.countunits(pofile, 4)
+ self.compareunit(pofile, 3, u'We aim to please \x96 will you aim too, please?')
+ self.compareunit(pofile, 4, u'South Africa\x92s language diversity can be challenging.')
+
+ def test_strip_html(self):
+ """Ensure that unnecessary html is stripped from the resulting unit."""
+
+ htmlsource = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>FMFI - Contact</title>
+</head>
+<body>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr align="left" valign="top">
+ <td width="150" height="556">
+ <table width="157" height="100%" border="0" cellspacing="0" id="leftmenubg-color">
+ <tr>
+ <td align="left" valign="top" height="555">
+ <table width="100%" border="0" cellspacing="0" cellpadding="2">
+ <tr align="left" valign="top" bgcolor="#660000">
+ <td width="4%"><strong></strong></td>
+ <td width="96%"><strong><font class="headingwhite">Projects</font></strong></td>
+ </tr>
+ <tr align="left" valign="top">
+ <td valign="middle" width="4%"><img src="images/arrow.gif" width="8" height="8"></td>
+ <td width="96%"><a href="index.html">Home Page</a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table></td>
+</table>
+</body>
+</html>
+'''
+ pofile = self.html2po(htmlsource)
+ self.countunits(pofile, 3)
+ self.compareunit(pofile, 2, u'Projects')
+ self.compareunit(pofile, 3, u'Home Page')
+
+ # Translate and convert back:
+ pofile.units[1].target = 'Projekte'
+ pofile.units[2].target = 'Tuisblad'
+ htmlresult = self.po2html(str(pofile), htmlsource).replace('\n', ' ').replace('= "', '="').replace('> <', '><')
+ snippet = '<td width="96%"><strong><font class="headingwhite">Projekte</font></strong></td>'
+ assert snippet in htmlresult
+ snippet = '<td width="96%"><a href="index.html">Tuisblad</a></td>'
+ assert snippet in htmlresult
+
+ def test_php(self):
+ """Test that PHP snippets don't interfere"""
+
+ # A simple string
+ self.check_phpsnippet('''<?=$phpvariable?>''')
+
+ # Contains HTML tag charcters (< and >)
+ self.check_phpsnippet('''<?=($a < $b ? $foo : ($b > c ? $bar : $cat))?>''')
+
+ # Make sure basically any symbol can be handled
+ self.check_phpsnippet(''' <? asdfghjkl qwertyuiop 1234567890!@#$%^&*()-=_+[]\{}|;':",./<>? ?> ''')
+
+ def test_multiple_php(self):
+ """Test multiple PHP snippets in a string to make sure they get restored properly"""
+ php1 = '''<?=$phpvariable?>'''
+ php2 = '''<?=($a < $b ? $foo : ($b > c ? $bar : $cat))?>'''
+ php3 = '''<? asdfghjklqwertyuiop1234567890!@#$%^&*()-=_+[]\{}|;':",./<>? ?>'''
+
+ # Put 3 different strings into an html string
+ innertext = '<a href="'+php1+'/site.html">Body text</a> and some '+php2+' more text '+php2+php3
+ htmlsource = '<html><head></head><body><p>'+innertext+'</p></body></html>'
+ self.check_single(htmlsource, innertext)
+
+ def test_php_multiline(self):
+
+ # A multi-line php string to test
+ php1 = '''<? abc
+def
+ghi ?>'''
+
+ # Scatter the php strings throughout the file, and show what the translation should be
+ innertext = '<a href="'+php1+'/site.html">Body text</a> and some '+php1+' more text '+php1+php1
+ innertrans = '<a href="'+php1+'/site.html">Texte de corps</a> et encore de '+php1+' plus de texte '+php1+php1
+
+ htmlsource = '<html><head></head><body><p>'+innertext+'</p></body></html>' # Current html file
+ transsource = '<html><head></head><body><p>'+innertrans+'</p></body></html>' # Expected translation
+
+ pofile = self.html2po(htmlsource)
+ pofile.units[0].target = innertrans # Register the translation in the PO file
+ htmlresult = self.po2html(pofile, htmlsource)
+ assert htmlresult == transsource
+
+ def test_comments(self):
+ """Test that HTML comments are converted to translator notes in output"""
+ pofile = self.html2po('<!-- comment outside block --><p><!-- a comment -->A paragraph<!-- with another comment -->.</p>', keepcomments=True)
+ self.compareunit(pofile, 1, 'A paragraph.')
+ notes = pofile.getunits()[0].getnotes()
+ assert unicode(notes) == ' a comment \n with another comment '
+
+class TestHTML2POCommand(test_convert.TestConvertCommand, TestHTML2PO):
+ """Tests running actual html2po commands on files"""
+ convertmodule = html2po
+ defaultoptions = {"progress": "none"}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-P, --pot")
+ options = self.help_check(options, "--duplicates=DUPLICATESTYLE")
+ options = self.help_check(options, "--keepcomments")
+ options = self.help_check(options, "-u, --untagged", last=True)
diff --git a/translate-toolkit-1.5.1/translate/convert/test_moz2po.py b/translate-toolkit-1.5.1/translate/convert/test_moz2po.py
new file mode 100644
index 0000000..059ae30
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_moz2po.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+
+from translate.convert import moz2po
+from translate.convert import test_convert
+
+class TestMoz2PO:
+ pass
+
+class TestMoz2POCommand(test_convert.TestConvertCommand, TestMoz2PO):
+ """Tests running actual moz2po commands on files"""
+ convertmodule = moz2po
+ defaultoptions = {"progress": "none"}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "--duplicates=DUPLICATESTYLE")
+ options = self.help_check(options, "-P, --pot")
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE", last=True)
diff --git a/translate-toolkit-1.5.1/translate/convert/test_mozfunny2prop.py b/translate-toolkit-1.5.1/translate/convert/test_mozfunny2prop.py
new file mode 100644
index 0000000..8184456
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_mozfunny2prop.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import mozfunny2prop
+from translate.misc import wStringIO
+from translate.storage import po
+
+class TestInc2PO:
+ def inc2po(self, incsource, inctemplate=None):
+ """helper that converts .inc source to po source without requiring files"""
+ inputfile = wStringIO.StringIO(incsource)
+ if inctemplate:
+ templatefile = wStringIO.StringIO(inctemplate)
+ else:
+ templatefile = None
+ outputfile = wStringIO.StringIO()
+ result = mozfunny2prop.inc2po(inputfile, outputfile, templatefile)
+ outputpo = outputfile.getvalue()
+ outputpofile = po.pofile(wStringIO.StringIO(outputpo))
+ return outputpofile
+
+ def singleelement(self, pofile):
+ """checks that the pofile contains a single non-header element, and returns it"""
+ assert len(pofile.units) == 2
+ assert pofile.units[0].isheader()
+ print pofile
+ return pofile.units[1]
+
+ def countelements(self, pofile):
+ """counts the number of non-header entries"""
+ assert pofile.units[0].isheader()
+ print pofile
+ return len(pofile.units) - 1
+
+ def test_simpleentry(self):
+ """checks that a simple inc entry converts properly to a po entry"""
+ incsource = '#define MOZ_LANGPACK_CREATOR mozilla.org\n'
+ pofile = self.inc2po(incsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.getlocations() == ["MOZ_LANGPACK_CREATOR"]
+ assert pounit.source == "mozilla.org"
+ assert pounit.target == ""
+
+ def test_uncomment_contributors(self):
+ """checks that the contributors entry is automatically uncommented"""
+ incsource = '''# If non-English locales wish to credit multiple contributors, uncomment this
+# variable definition and use the format specified.
+# #define MOZ_LANGPACK_CONTRIBUTORS <em:contributor>Joe Solon</em:contributor> <em:contributor>Suzy Solon</em:contributor>'''
+ pofile = self.inc2po(incsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.getlocations() == ["MOZ_LANGPACK_CONTRIBUTORS"]
+ assert "Joe Solon" in pounit.source
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_oo2po.py b/translate-toolkit-1.5.1/translate/convert/test_oo2po.py
new file mode 100644
index 0000000..94f884d
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_oo2po.py
@@ -0,0 +1,228 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import oo2po
+from translate.convert import po2oo
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+from translate.storage.poheader import poheader
+from translate.storage import oo
+import os
+
+class TestOO2PO:
+ target_filetype = po.pofile
+ conversion_module = oo2po
+ conversion_class = oo2po.oo2po
+
+ def convert(self, oosource, sourcelanguage='en-US', targetlanguage='af-ZA'):
+ """helper that converts oo source to po source without requiring files"""
+ inputoo = oo.oofile(oosource)
+ convertor = self.conversion_class(sourcelanguage, targetlanguage)
+ outputpo = convertor.convertstore(inputoo)
+ return outputpo
+
+ def singleelement(self, pofile):
+ """checks that the pofile contains a single non-header element, and returns it"""
+ if isinstance(pofile, poheader):
+ assert len(pofile.units) == 2
+ assert pofile.units[0].isheader()
+ return pofile.units[1]
+ else:
+ assert len(pofile.units) == 1
+ return pofile.units[0]
+
+ def roundtripstring(self, filename, entitystring):
+ """Convert the supplied string as part of an OpenOffice.org GSI file to po and back.
+
+ Return the string once it has been through all the conversions."""
+
+ ootemplate = r'helpcontent2 %s 0 help par_id3150670 35 0 en-US %s 2002-02-02 02:02:02'
+
+ oosource = ootemplate % (filename, entitystring)
+ ooinputfile = wStringIO.StringIO(oosource)
+ ootemplatefile = wStringIO.StringIO(oosource)
+ pooutputfile = wStringIO.StringIO()
+
+ self.conversion_module.convertoo(ooinputfile, pooutputfile, ootemplatefile, targetlanguage='en-US')
+ posource = pooutputfile.getvalue()
+
+ poinputfile = wStringIO.StringIO(posource)
+ ootemplatefile = wStringIO.StringIO(oosource)
+ oooutputfile = wStringIO.StringIO()
+ po2oo.convertoo(poinputfile, oooutputfile, ootemplatefile, targetlanguage="en-US")
+ ooresult = oooutputfile.getvalue()
+ print "original oo:\n", oosource, "po version:\n", posource, "output oo:\n", ooresult
+ return ooresult.split('\t')[10]
+
+ def check_roundtrip(self, filename, text):
+ """Checks that the text converted to po and back is the same as the original."""
+ assert self.roundtripstring(filename, text) == text
+
+ def test_simpleentity(self):
+ """checks that a simple oo entry converts properly to a po entry"""
+ oosource = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US Character 20050924 09:13:58'
+ pofile = self.convert(oosource)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "Character"
+ assert pounit.target == ""
+
+ def test_escapes(self):
+ """checks that a simple oo entry converts escapes properly to a po entry"""
+ oosource = r"wizards source\formwizard\dbwizres.src 0 string RID_DB_FORM_WIZARD_START + 19 0 en-US Newline \n Newline Tab \t Tab CR \r CR 20050924 09:13:58"
+ pofile = self.convert(oosource)
+ pounit = self.singleelement(pofile)
+ poelementsrc = str(pounit)
+ print poelementsrc
+ assert "Newline \n Newline" in pounit.source
+ assert "Tab \t Tab" in pounit.source
+ assert "CR \r CR" in pounit.source
+
+ def test_roundtrip_escape(self):
+ self.check_roundtrip('strings.src', r'The given command is not a SELECT statement.\nOnly queries are allowed.')
+ self.check_roundtrip('source\ui\dlg\AutoControls_tmpl.hrc', r';\t59\t,\t44\t:\t58\t{Tab}\t9\t{Space}\t32')
+ self.check_roundtrip('inc_openoffice\windows\msi_languages\Nsis.ulf', r'The installation files must be unpacked and copied to your hard disk in preparation for the installation. After that, the %PRODUCTNAME installation will start automatically.\r\n\r\nClick \'Next\' to continue.')
+ self.check_roundtrip('file.xhp', r'\<ahelp\>')
+ self.check_roundtrip('file.xhp', r'\<ahelp prop=\"value\"\>')
+ self.check_roundtrip('file.xhp', r'\<ahelp prop=\"value\"\>marked up text\</ahelp\>')
+ self.check_roundtrip('file.xhp', r'\<ahelp prop=\"value>>\"\>')
+ self.check_roundtrip('file.xhp', r'''\<ahelp prop=\"value>>\"\>'Next'>> or "<<Previous"\</ahelp\>''')
+ self.check_roundtrip('address_auto.xhp', r'''example, \<item type=\"literal\"\>'Harry\\'s Bar'.\</item\>''')
+
+ def xtest_roundtrip_whitespaceonly(self):
+ """check items that are only special instances of whitespce"""
+ # FIXME We can't roundtrip this yet because of some problems in the oo class handling
+ self.check_roundtrip('choose_chart_type.xhp', r' ')
+ self.check_roundtrip('choose_chart_type.xhp', '\xc2\xa0')
+
+ def test_double_escapes(self):
+ oosource = r"helpcontent2 source\text\shared\01\02100001.xhp 0 help par_id3150670 35 0 en-US \\< 2002-02-02 02:02:02"
+ pofile = self.convert(oosource)
+ pounit = self.singleelement(pofile)
+ poelementsrc = str(pounit)
+ print poelementsrc
+ assert pounit.source == r"\<"
+
+ def test_escapes_helpcontent2(self):
+ """checks that a helpcontent2 entry converts escapes properly to a po entry"""
+ oosource = r"helpcontent2 source\text\smath\guide\parentheses.xhp 0 help par_id3150344 4 0 en-US size *2 \\langle x \\rangle 2002-02-02 02:02:02"
+ pofile = self.convert(oosource)
+ pounit = self.singleelement(pofile)
+ poelementsrc = str(pounit)
+ print poelementsrc
+ assert pounit.source == r'size *2 \langle x \rangle'
+
+ def test_msgid_bug_error_address(self):
+ """tests the we have the correct url for reporting msgid bugs"""
+ oosource = r"wizards source\formwizard\dbwizres.src 0 string RID_DB_FORM_WIZARD_START + 19 0 en-US Newline \n Newline Tab \t Tab CR \r CR 20050924 09:13:58"
+ bug_url = '''http://qa.openoffice.org/issues/enter_bug.cgi''' + ('''?subcomponent=ui&comment=&short_desc=Localization issue in file: &component=l10n&form_name=enter_issue''').replace(" ", "%20").replace(":", "%3A")
+ pofile = self.convert(oosource)
+ assert pofile.units[0].isheader()
+ assert pofile.parseheader()["Report-Msgid-Bugs-To"] == bug_url
+
+ def test_x_comment_inclusion(self):
+ """test that we can merge x-comment language entries into comment sections of the PO file"""
+ en_USsource = r"wizards source\formwizard\dbwizres.src 0 string RID_DB_FORM_WIZARD_START + 19 0 en-US Text Quickhelp Title 20050924 09:13:58"
+ xcommentsource = r"wizards source\formwizard\dbwizres.src 0 string RID_DB_FORM_WIZARD_START + 19 0 x-comment %s %s %s 20050924 09:13:58"
+ # Real comment
+ comment = "Comment"
+ commentsource = en_USsource + '\n' + xcommentsource % (comment, comment, comment)
+ pofile = self.convert(commentsource)
+ if isinstance(pofile, poheader):
+ units = pofile.units[1:]
+ else:
+ units = pofile.units
+ textunit = units[0]
+ assert textunit.source == "Text"
+ assert comment in textunit.getnotes("developer")
+ quickhelpunit = units[1]
+ assert quickhelpunit.source == "Quickhelp"
+ assert comment in quickhelpunit.getnotes("developer")
+ titleunit = units[2]
+ assert titleunit.source == "Title"
+ assert comment in titleunit.getnotes("developer")
+ # Whitespace and blank
+ for comment in (" ", ""):
+ commentsource = en_USsource + '\n' + xcommentsource % (comment, comment, comment)
+ pofile = self.convert(commentsource)
+ if isinstance(pofile, poheader):
+ units = pofile.units[1:]
+ else:
+ units = pofile.units
+ textunit = units[0]
+ assert textunit.source == "Text"
+ assert textunit.getnotes("developer") == ""
+ quickhelpunit = units[1]
+ assert quickhelpunit.source == "Quickhelp"
+ assert quickhelpunit.getnotes("developer") == ""
+ titleunit = units[2]
+ assert titleunit.source == "Title"
+ assert titleunit.getnotes("developer") == ""
+
+class TestOO2POCommand(test_convert.TestConvertCommand, TestOO2PO):
+ """Tests running actual oo2po commands on files"""
+ convertmodule = oo2po
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "--source-language=LANG")
+ options = self.help_check(options, "--language=LANG")
+ options = self.help_check(options, "-P, --pot")
+ options = self.help_check(options, "--duplicates=DUPLICATESTYLE")
+ options = self.help_check(options, "--multifile=MULTIFILESTYLE")
+ options = self.help_check(options, "--nonrecursiveinput", last=True)
+
+ def test_preserve_filename(self):
+ """Ensures that the filename is preserved."""
+ oosource = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US Character 20050924 09:13:58'
+ self.create_testfile("snippet.sdf", oosource)
+ oofile = oo.oofile(self.open_testfile("snippet.sdf"))
+ assert oofile.filename.endswith("snippet.sdf")
+ oofile.parse(oosource)
+ assert oofile.filename.endswith("snippet.sdf")
+
+ def test_simple_pot(self):
+ """tests the simplest possible conversion to a pot file"""
+ oosource = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US Character 20050924 09:13:58'
+ self.create_testfile("simple.oo", oosource)
+ self.run_command("simple.oo", "simple.pot", pot=True, nonrecursiveinput=True)
+ pofile = self.target_filetype(self.open_testfile("simple.pot"))
+ poelement = self.singleelement(pofile)
+ assert poelement.source == "Character"
+ assert poelement.target == ""
+
+ def test_simple_po(self):
+ """tests the simplest possible conversion to a po file"""
+ oosource1 = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US Character 20050924 09:13:58'
+ oosource2 = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 ku Karakter 20050924 09:13:58'
+ self.create_testfile("simple.oo", oosource1 + "\n" + oosource2)
+ self.run_command("simple.oo", "simple.po", lang="ku", nonrecursiveinput=True)
+ pofile = self.target_filetype(self.open_testfile("simple.po"))
+ poelement = self.singleelement(pofile)
+ assert poelement.source == "Character"
+ assert poelement.target == "Karakter"
+
+ def test_onefile_nonrecursive(self):
+ """tests the --multifile=onefile option and make sure it doesn't produce a directory"""
+ oosource = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US Character 20050924 09:13:58'
+ self.create_testfile("simple.oo", oosource)
+ self.run_command("simple.oo", "simple.pot", pot=True, multifile="onefile")
+ assert os.path.isfile(self.get_testfilename("simple.pot"))
+
+ def test_remove_duplicates(self):
+ """test that removing of duplicates works correctly (bug 171)"""
+ oosource = r'''
+sd source\ui\animations\SlideTransitionPane.src 0 checkbox DLG_SLIDE_TRANSITION_PANE CB_AUTO_PREVIEW HID_SD_SLIDETRANSITIONPANE_CB_AUTO_PREVIEW 1 en-US Automatic preview 20060725 03:26:42
+sd source\ui\animations\AnimationSchemesPane.src 0 checkbox DLG_ANIMATION_SCHEMES_PANE CB_AUTO_PREVIEW HID_SD_ANIMATIONSCHEMESPANE_CB_AUTO_PREVIEW 1 en-US Automatic preview 20060725 03:26:42
+sd source\ui\animations\CustomAnimationCreateDialog.src 0 checkbox RID_TP_CUSTOMANIMATION_ENTRANCE CBX_PREVIEW 143 en-US Automatic preview 20060725 03:26:42
+sd source\ui\animations\CustomAnimationCreateDialog.src 0 checkbox RID_TP_CUSTOMANIMATION_ENTRANCE CBX_PREVIEW 143 fr Aperçu automatique 20060725 03:26:42
+sd source\ui\animations\CustomAnimationSchemesPane.src 0 checkbox DLG_CUSTOMANIMATION_SCHEMES_PANE 4 0 en-US Automatic preview 20060725 03:26:42
+sd source\ui\animations\CustomAnimationSchemesPane.src 0 checkbox DLG_CUSTOMANIMATION_SCHEMES_PANE 4 0 fr Aperçu automatique 20060725 03:26:42
+'''
+ self.create_testfile("simple.oo", oosource)
+ self.run_command("simple.oo", "simple.po", language="fr", multifile="onefile", error="traceback", duplicates="merge")
+ pofile = self.target_filetype(self.open_testfile("simple.po"))
+ assert len(pofile.units) == 2
+ assert pofile.units[1].target == u"Aperçu automatique"
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_oo2xliff.py b/translate-toolkit-1.5.1/translate/convert/test_oo2xliff.py
new file mode 100644
index 0000000..4e9f2c4
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_oo2xliff.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import test_oo2po
+from translate.convert import oo2xliff
+from translate.convert import xliff2oo
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import xliff
+from translate.storage import oo
+import os
+
+class TestOO2XLIFF(test_oo2po.TestOO2PO):
+ target_filetype = xliff.xlifffile
+ conversion_module = oo2xliff
+ conversion_class = oo2xliff.oo2xliff
+
+ def test_msgid_bug_error_address(self):
+ pass
+
+class TestOO2POCommand(test_convert.TestConvertCommand, TestOO2XLIFF):
+ """Tests running actual oo2xliff commands on files"""
+ convertmodule = oo2xliff
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "--source-language=LANG")
+ options = self.help_check(options, "--language=LANG")
+ options = self.help_check(options, "--duplicates=DUPLICATESTYLE")
+ options = self.help_check(options, "--multifile=MULTIFILESTYLE")
+ options = self.help_check(options, "--nonrecursiveinput", last=True)
+
+ def test_preserve_filename(self):
+ """Ensures that the filename is preserved."""
+ oosource = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US Character 20050924 09:13:58'
+ self.create_testfile("snippet.sdf", oosource)
+ oofile = oo.oofile(self.open_testfile("snippet.sdf"))
+ assert oofile.filename.endswith("snippet.sdf")
+ oofile.parse(oosource)
+ assert oofile.filename.endswith("snippet.sdf")
+
+ def test_simple_xlf(self):
+ """tests the simplest possible conversion to a xlf file"""
+ oosource = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US Character 20050924 09:13:58'
+ self.create_testfile("simple.oo", oosource)
+ self.run_command("simple.oo", "simple.xlf", lang="ku", nonrecursiveinput=True)
+ pofile = self.target_filetype(self.open_testfile("simple.xlf"))
+ poelement = self.singleelement(pofile)
+ assert poelement.source == "Character"
+ assert poelement.target == ""
+
+ def test_simple_po(self):
+ """tests the simplest possible conversion to a po file"""
+ oosource1 = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US Character 20050924 09:13:58'
+ oosource2 = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 ku Karakter 20050924 09:13:58'
+ self.create_testfile("simple.oo", oosource1 + "\n" + oosource2)
+ self.run_command("simple.oo", "simple.po", lang="ku", nonrecursiveinput=True)
+ pofile = self.target_filetype(self.open_testfile("simple.po"))
+ poelement = self.singleelement(pofile)
+ assert poelement.source == "Character"
+ assert poelement.target == "Karakter"
+
+ def test_onefile_nonrecursive(self):
+ """tests the --multifile=onefile option and make sure it doesn't produce a directory"""
+ oosource = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US Character 20050924 09:13:58'
+ self.create_testfile("simple.oo", oosource)
+ self.run_command("simple.oo", "simple.xlf", lang="ku", multifile="onefile")
+ assert os.path.isfile(self.get_testfilename("simple.xlf"))
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_php2po.py b/translate-toolkit-1.5.1/translate/convert/test_php2po.py
new file mode 100644
index 0000000..0cb93b4
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_php2po.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import php2po
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+from translate.storage import php
+
+class TestPhp2PO:
+ def php2po(self, phpsource, phptemplate=None):
+ """helper that converts .phperties source to po source without requiring files"""
+ inputfile = wStringIO.StringIO(phpsource)
+ inputphp = php.phpfile(inputfile)
+ convertor = php2po.php2po()
+ if phptemplate:
+ templatefile = wStringIO.StringIO(phptemplate)
+ templatephp = php.phpfile(templatefile)
+ outputpo = convertor.mergestore(templatephp, inputphp)
+ else:
+ outputpo = convertor.convertstore(inputphp)
+ return outputpo
+
+ def convertphp(self, phpsource):
+ """call the convertphp, return the outputfile"""
+ inputfile = wStringIO.StringIO(phpsource)
+ outputfile = wStringIO.StringIO()
+ templatefile = None
+ assert php2po.convertphp(inputfile, outputfile, templatefile)
+ return outputfile.getvalue()
+
+ def singleelement(self, pofile):
+ """checks that the pofile contains a single non-header element, and returns it"""
+ assert len(pofile.units) == 2
+ assert pofile.units[0].isheader()
+ print pofile
+ return pofile.units[1]
+
+ def countelements(self, pofile):
+ """counts the number of non-header entries"""
+ assert pofile.units[0].isheader()
+ print pofile
+ return len(pofile.units) - 1
+
+ def test_simpleentry(self):
+ """checks that a simple php entry converts properly to a po entry"""
+ phpsource = """$_LANG['simple'] = 'entry';"""
+ pofile = self.php2po(phpsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "entry"
+ assert pounit.target == ""
+
+ def test_convertphp(self):
+ """checks that the convertphp function is working"""
+ phpsource = """$_LANG['simple'] = 'entry';"""
+ posource = self.convertphp(phpsource)
+ pofile = po.pofile(wStringIO.StringIO(posource))
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "entry"
+ assert pounit.target == ""
+
+ def test_unicode(self):
+ """checks that unicode entries convert properly"""
+ unistring = u'Norsk bokm\u00E5l'
+ phpsource = """$lang['nb'] = '%s';""" % unistring
+ pofile = self.php2po(phpsource)
+ pounit = self.singleelement(pofile)
+ print repr(pofile.units[0].target)
+ print repr(pounit.source)
+ assert pounit.source == u'Norsk bokm\u00E5l'
+
+ def test_multiline(self):
+ """checks that multiline enties can be parsed"""
+ phpsource = r"""$lang['5093'] = 'Unable to connect to your IMAP server. You may have exceeded the maximum number
+of connections to this server. If so, use the Advanced IMAP Server Settings dialog to
+reduce the number of cached connections.';"""
+ pofile = self.php2po(phpsource)
+ print repr(pofile.units[1].target)
+ assert self.countelements(pofile) == 1
+
+ def test_comments_before(self):
+ """test to ensure that we take comments from .php and place them in .po"""
+ phpsource = '''/* Comment */
+$lang['prefPanel-smime'] = 'Security';'''
+ pofile = self.php2po(phpsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.getnotes("developer") == "/* Comment"
+ # TODO write test for inline comments and check for // comments that precede an entry
+
+ def test_emptyentry(self):
+ """checks that empty definitions survives into po file"""
+ phpsource = '''/* comment */\n$lang['credit'] = '';'''
+ pofile = self.php2po(phpsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.getlocations() == ["$lang['credit']"]
+ assert pounit.getcontext() == "$lang['credit']"
+ assert "#. /* comment" in str(pofile)
+ assert pounit.source == ""
+
+ def test_emptyentry_translated(self):
+ """checks that if we translate an empty definition it makes it into the PO"""
+ phptemplate = '''$lang['credit'] = '';'''
+ phpsource = '''$lang['credit'] = 'Translators Names';'''
+ pofile = self.php2po(phpsource, phptemplate)
+ pounit = self.singleelement(pofile)
+ assert pounit.getlocations() == ["$lang['credit']"]
+ assert pounit.source == ""
+ assert pounit.target == "Translators Names"
+
+ def test_newlines_in_value(self):
+ """check that we can carry newlines that appear in the entry value into the PO"""
+ # Single quotes - \n is not a newline
+ phpsource = r'''$lang['name'] = 'value1\nvalue2';'''
+ pofile = self.php2po(phpsource)
+ unit = self.singleelement(pofile)
+ assert unit.source == r"value1\nvalue2"
+ # Double quotes - \n is a newline
+ phpsource = r'''$lang['name'] = "value1\nvalue2";'''
+ pofile = self.php2po(phpsource)
+ unit = self.singleelement(pofile)
+ assert unit.source == "value1\nvalue2"
+
+ def test_spaces_in_name(self):
+ """checks that if we have spaces in the name we create a good PO with no spaces"""
+ phptemplate = '''$lang[ 'credit' ] = 'Something';'''
+ phpsource = '''$lang[ 'credit' ] = ''n Ding';'''
+ pofile = self.php2po(phpsource, phptemplate)
+ pounit = self.singleelement(pofile)
+ assert pounit.getlocations() == ["$lang['credit']"]
+
+class TestPhp2POCommand(test_convert.TestConvertCommand, TestPhp2PO):
+ """Tests running actual php2po commands on files"""
+ convertmodule = php2po
+ defaultoptions = {"progress": "none"}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-P, --pot")
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "--duplicates=DUPLICATESTYLE", last=True)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2csv.py b/translate-toolkit-1.5.1/translate/convert/test_po2csv.py
new file mode 100644
index 0000000..eca2896
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2csv.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+
+from translate.convert import po2csv
+from translate.convert import csv2po
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+from translate.storage import csvl10n
+
+class TestPO2CSV:
+ def po2csv(self, posource):
+ """helper that converts po source to csv source without requiring files"""
+ inputfile = wStringIO.StringIO(posource)
+ inputpo = po.pofile(inputfile)
+ convertor = po2csv.po2csv()
+ outputcsv = convertor.convertstore(inputpo)
+ return outputcsv
+
+ def csv2po(self, csvsource, template=None):
+ """helper that converts csv source to po source without requiring files"""
+ inputfile = wStringIO.StringIO(csvsource)
+ inputcsv = csvl10n.csvfile(inputfile)
+ if template:
+ templatefile = wStringIO.StringIO(template)
+ inputpot = po.pofile(templatefile)
+ else:
+ inputpot = None
+ convertor = csv2po.csv2po(templatepo=inputpot)
+ outputpo = convertor.convertstore(inputcsv)
+ return outputpo
+
+ def singleelement(self, storage):
+ """checks that the pofile contains a single non-header element, and returns it"""
+ assert len(storage.units) == 1
+ return storage.units[0]
+
+ def test_simpleentity(self):
+ """checks that a simple csv entry definition converts properly to a po entry"""
+ minipo = r'''#: term.cpp
+msgid "Term"
+msgstr "asdf"'''
+ csvfile = self.po2csv(minipo)
+ unit = self.singleelement(csvfile)
+ assert unit.comment == "term.cpp"
+ assert unit.source == "Term"
+ assert unit.target == "asdf"
+
+ def test_multiline(self):
+ """tests multiline po entries"""
+ minipo = r'''msgid "First part "
+"and extra"
+msgstr "Eerste deel "
+"en ekstra"'''
+ csvfile = self.po2csv(minipo)
+ unit = self.singleelement(csvfile)
+ assert unit.source == "First part and extra"
+ assert unit.target == "Eerste deel en ekstra"
+
+ def test_escapednewlines(self):
+ """Test the escaping of newlines"""
+ minipo = r'''msgid "First line\nSecond line"
+msgstr "Eerste lyn\nTweede lyn"
+'''
+ csvfile = self.po2csv(minipo)
+ unit = self.singleelement(csvfile)
+ assert unit.source == "First line\nSecond line"
+ assert unit.target == "Eerste lyn\nTweede lyn"
+ pofile = self.csv2po(str(csvfile))
+ unit = self.singleelement(pofile)
+ assert unit.source == "First line\nSecond line"
+ assert unit.target == "Eerste lyn\nTweede lyn"
+
+ def test_escapedtabs(self):
+ """Test the escaping of tabs"""
+ minipo = r'''msgid "First column\tSecond column"
+msgstr "Eerste kolom\tTweede kolom"
+'''
+ csvfile = self.po2csv(minipo)
+ unit = self.singleelement(csvfile)
+ assert unit.source == "First column\tSecond column"
+ assert unit.target == "Eerste kolom\tTweede kolom"
+ assert csvfile.findunit("First column\tSecond column").target == "Eerste kolom\tTweede kolom"
+
+ def test_escapedquotes(self):
+ """Test the escaping of quotes (and slash)"""
+ minipo = r'''msgid "Hello \"Everyone\""
+msgstr "Good day \"All\""
+
+msgid "Use \\\"."
+msgstr "Gebruik \\\"."
+'''
+ csvfile = self.po2csv(minipo)
+ assert csvfile.findunit('Hello "Everyone"').target == 'Good day "All"'
+ assert csvfile.findunit('Use \\".').target == 'Gebruik \\".'
+
+ def test_escapedescape(self):
+ """Test the escaping of pure escapes is unaffected"""
+ minipo = r'''msgid "Find\\Options"
+msgstr "Vind\\Opsies"
+'''
+ csvfile = self.po2csv(minipo)
+ print minipo
+ print csvfile
+ assert csvfile.findunit(r'Find\Options').target == r'Vind\Opsies'
+
+ def test_singlequotes(self):
+ """Tests that single quotes are preserved correctly"""
+ minipo = '''msgid "source 'source'"\nmsgstr "target 'target'"\n'''
+ csvfile = self.po2csv(minipo)
+ print str(csvfile)
+ assert csvfile.findunit("source 'source'").target == "target 'target'"
+ # Make sure we don't mess with start quotes until writing
+ minipo = '''msgid "'source'"\nmsgstr "'target'"\n'''
+ csvfile = self.po2csv(minipo)
+ print str(csvfile)
+ assert csvfile.findunit(r"'source'").target == r"'target'"
+ # TODO check that we escape on writing not in the internal representation
+
+ def test_empties(self):
+ """Tests that things keep working with empty entries"""
+ minipo = 'msgid "Source"\nmsgstr ""\n\nmsgid ""\nmsgstr ""'
+ csvfile = self.po2csv(minipo)
+ assert csvfile.findunit("Source") is not None
+ assert csvfile.findunit("Source").target == ""
+ assert len(csvfile.units) == 1
+
+ def test_kdecomments(self):
+ """test that we don't carry KDE comments to CSV"""
+ minipo = '#: simple.c\nmsgid "_: KDE comment\\n"\n"Same"\nmsgstr "Same"\n'
+ csvfile = self.po2csv(minipo)
+ unit = self.singleelement(csvfile)
+ assert unit.source == "Same"
+ assert unit.target == "Same"
+
+class TestPO2CSVCommand(test_convert.TestConvertCommand, TestPO2CSV):
+ """Tests running actual po2csv commands on files"""
+ convertmodule = po2csv
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-P, --pot")
+ options = self.help_check(options, "--columnorder=COLUMNORDER", last=True)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2dtd.py b/translate-toolkit-1.5.1/translate/convert/test_po2dtd.py
new file mode 100644
index 0000000..2ce297c
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2dtd.py
@@ -0,0 +1,285 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import po2dtd
+from translate.convert import dtd2po
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+from translate.storage import dtd
+from py import test
+import warnings
+
+class TestPO2DTD:
+ def setup_method(self, method):
+ warnings.resetwarnings()
+
+ def teardown_method(self, method):
+ warnings.resetwarnings()
+
+ def po2dtd(self, posource):
+ """helper that converts po source to dtd source without requiring files"""
+ inputfile = wStringIO.StringIO(posource)
+ inputpo = po.pofile(inputfile)
+ convertor = po2dtd.po2dtd()
+ outputdtd = convertor.convertstore(inputpo)
+ return outputdtd
+
+ def merge2dtd(self, dtdsource, posource):
+ """helper that merges po translations to dtd source without requiring files"""
+ inputfile = wStringIO.StringIO(posource)
+ inputpo = po.pofile(inputfile)
+ templatefile = wStringIO.StringIO(dtdsource)
+ templatedtd = dtd.dtdfile(templatefile)
+ convertor = po2dtd.redtd(templatedtd)
+ outputdtd = convertor.convertstore(inputpo)
+ return outputdtd
+
+ def convertdtd(self, posource, dtdtemplate):
+ """helper to exercise the command line function"""
+ inputfile = wStringIO.StringIO(posource)
+ outputfile = wStringIO.StringIO()
+ templatefile = wStringIO.StringIO(dtdtemplate)
+ assert po2dtd.convertdtd(inputfile, outputfile, templatefile)
+ return outputfile.getvalue()
+
+ def roundtripsource(self, dtdsource):
+ """converts dtd source to po and back again, returning the resulting source"""
+ dtdinputfile = wStringIO.StringIO(dtdsource)
+ dtdinputfile2 = wStringIO.StringIO(dtdsource)
+ pooutputfile = wStringIO.StringIO()
+ dtd2po.convertdtd(dtdinputfile, pooutputfile, dtdinputfile2)
+ posource = pooutputfile.getvalue()
+ poinputfile = wStringIO.StringIO(posource)
+ dtdtemplatefile = wStringIO.StringIO(dtdsource)
+ dtdoutputfile = wStringIO.StringIO()
+ po2dtd.convertdtd(poinputfile, dtdoutputfile, dtdtemplatefile)
+ dtdresult = dtdoutputfile.getvalue()
+ print "original dtd:\n", dtdsource, "po version:\n", posource, "output dtd:\n", dtdresult
+ return dtdresult
+
+ def roundtripstring(self, entitystring):
+ """Just takes the contents of a ENTITY definition (with quotes) and does a roundtrip on that"""
+ dtdintro, dtdoutro = '<!ENTITY Test.RoundTrip ', '>\n'
+ dtdsource = dtdintro + entitystring + dtdoutro
+ dtdresult = self.roundtripsource(dtdsource)
+ assert dtdresult.startswith(dtdintro) and dtdresult.endswith(dtdoutro)
+ return dtdresult[len(dtdintro):-len(dtdoutro)]
+
+ def check_roundtrip(self, dtdsource):
+ """Checks that the round-tripped string is the same as the original"""
+ assert self.roundtripstring(dtdsource) == dtdsource
+
+ def test_joinlines(self):
+ """tests that po lines are joined seamlessly (bug 16)"""
+ multilinepo = '''#: pref.menuPath\nmsgid ""\n"<span>Tools &gt; Options</"\n"span>"\nmsgstr ""\n'''
+ dtdfile = self.po2dtd(multilinepo)
+ dtdsource = str(dtdfile)
+ assert "</span>" in dtdsource
+
+ def test_escapedstr(self):
+ """tests that \n in msgstr is escaped correctly in dtd"""
+ multilinepo = '''#: pref.menuPath\nmsgid "Hello\\nEveryone"\nmsgstr "Good day\\nAll"\n'''
+ dtdfile = self.po2dtd(multilinepo)
+ dtdsource = str(dtdfile)
+ assert "Good day\nAll" in dtdsource
+
+ def test_missingaccesskey(self):
+ """tests that proper warnings are given if access key is missing"""
+ simplepo = '''#: simple.label\n#: simple.accesskey\nmsgid "Simple &String"\nmsgstr "Dimpled Ring"\n'''
+ simpledtd = '''<!ENTITY simple.label "Simple String">\n<!ENTITY simple.accesskey "S">'''
+ warnings.simplefilter("error")
+ assert test.raises(Warning, self.merge2dtd, simpledtd, simplepo)
+
+ def test_accesskeycase(self):
+ """tests that access keys come out with the same case as the original, regardless"""
+ simplepo_template = '''#: simple.label\n#: simple.accesskey\nmsgid "%s"\nmsgstr "%s"\n'''
+ simpledtd_template = '''<!ENTITY simple.label "Simple %s">\n<!ENTITY simple.accesskey "%s">'''
+ possibilities = [
+ #(en label, en akey, en po, af po, af label, expected af akey)
+ ("Sis", "S", "&Sis", "&Sies", "Sies", "S"),
+ ("Sis", "s", "Si&s", "&Sies", "Sies", "S"),
+ ("Sis", "S", "&Sis", "Sie&s", "Sies", "s"),
+ ("Sis", "s", "Si&s", "Sie&s", "Sies", "s"),
+ # untranslated strings should have the casing of the source
+ ("Sis", "S", "&Sis", "", "Sis", "S"),
+ ("Sis", "s", "Si&s", "", "Sis", "s"),
+ ("Suck", "S", "&Suck", "", "Suck", "S"),
+ ("Suck", "s", "&Suck", "", "Suck", "s"),
+ ]
+ for (en_label, en_akey, po_source, po_target, target_label, target_akey) in possibilities:
+ simplepo = simplepo_template % (po_source, po_target)
+ simpledtd = simpledtd_template % (en_label, en_akey)
+ dtdfile = self.merge2dtd(simpledtd, simplepo)
+ dtdfile.makeindex()
+ accel = dtd.unquotefromdtd(dtdfile.index["simple.accesskey"].definition)
+ assert accel == target_akey
+
+ def test_accesskey_types(self):
+ """tests that we can detect the various styles of accesskey"""
+ simplepo_template = '''#: simple.%s\n#: simple.%s\nmsgid "&File"\nmsgstr "F&aele"\n'''
+ simpledtd_template = '''<!ENTITY simple.%s "File">\n<!ENTITY simple.%s "a">'''
+ for label in ("label", "title"):
+ for accesskey in ("accesskey", "accessKey", "akey"):
+ simplepo = simplepo_template % (label, accesskey)
+ simpledtd = simpledtd_template % (label, accesskey)
+ dtdfile = self.merge2dtd(simpledtd, simplepo)
+ dtdfile.makeindex()
+ assert dtd.unquotefromdtd(dtdfile.index["simple.%s" % accesskey].definition) == "a"
+
+ def test_ampersandfix(self):
+ """tests that invalid ampersands are fixed in the dtd"""
+ simplestring = '''#: simple.string\nmsgid "Simple String"\nmsgstr "Dimpled &Ring"\n'''
+ dtdfile = self.po2dtd(simplestring)
+ dtdsource = str(dtdfile)
+ assert "Dimpled Ring" in dtdsource
+
+ po_snippet = r'''#: searchIntegration.label
+#: searchIntegration.accesskey
+msgid "Allow &searchIntegration.engineName; to &search messages"
+msgstr "&searchIntegration.engineName; &ileti aramasına izin ver"
+'''
+ dtd_snippet = r'''<!ENTITY searchIntegration.accesskey "s">
+<!ENTITY searchIntegration.label "Allow &searchIntegration.engineName; to search messages">'''
+ dtdfile = self.merge2dtd(dtd_snippet, po_snippet)
+ dtdsource = str(dtdfile)
+ print dtdsource
+ assert '"&searchIntegration.engineName; ileti aramasına izin ver"' in dtdsource
+
+ def test_entities_two(self):
+ """test the error ouput when we find two entities"""
+ simplestring = '''#: simple.string second.string\nmsgid "Simple String"\nmsgstr "Dimpled Ring"\n'''
+ dtdfile = self.po2dtd(simplestring)
+ dtdsource = str(dtdfile)
+ assert "CONVERSION NOTE - multiple entities" in dtdsource
+
+ def test_entities(self):
+ """tests that entities are correctly idnetified in the dtd"""
+ simplestring = '''#: simple.string\nmsgid "Simple String"\nmsgstr "Dimpled Ring"\n'''
+ dtdfile = self.po2dtd(simplestring)
+ dtdsource = str(dtdfile)
+ assert dtdsource.startswith("<!ENTITY simple.string")
+
+ def test_comments_translator(self):
+ """tests for translator comments"""
+ simplestring = '''# Comment1\n# Comment2\n#: simple.string\nmsgid "Simple String"\nmsgstr "Dimpled Ring"\n'''
+ dtdfile = self.po2dtd(simplestring)
+ dtdsource = str(dtdfile)
+ assert dtdsource.startswith("<!-- Comment1 -->")
+
+ def test_retains_hashprefix(self):
+ """tests that hash prefixes in the dtd are retained"""
+ hashpo = '''#: lang.version\nmsgid "__MOZILLA_LOCALE_VERSION__"\nmsgstr "__MOZILLA_LOCALE_VERSION__"\n'''
+ hashdtd = '#expand <!ENTITY lang.version "__MOZILLA_LOCALE_VERSION__">\n'
+ dtdfile = self.merge2dtd(hashdtd, hashpo)
+ regendtd = str(dtdfile)
+ assert regendtd == hashdtd
+
+ def test_convertdtd(self):
+ """checks that the convertdtd function is working"""
+ posource = '''#: simple.label\n#: simple.accesskey\nmsgid "Simple &String"\nmsgstr "Dimpled &Ring"\n'''
+ dtdtemplate = '''<!ENTITY simple.label "Simple String">\n<!ENTITY simple.accesskey "S">\n'''
+ dtdexpected = '''<!ENTITY simple.label "Dimpled Ring">\n<!ENTITY simple.accesskey "R">\n'''
+ newdtd = self.convertdtd(posource, dtdtemplate)
+ print newdtd
+ assert newdtd == dtdexpected
+
+ def test_newlines_escapes(self):
+ """check that we can handle a \n in the PO file"""
+ posource = '''#: simple.label\n#: simple.accesskey\nmsgid "A hard coded newline.\\n"\nmsgstr "Hart gekoeerde nuwe lyne\\n"\n'''
+ dtdtemplate = '<!ENTITY simple.label "A hard coded newline.\n">\n'
+ dtdexpected = '''<!ENTITY simple.label "Hart gekoeerde nuwe lyne\n">\n'''
+ dtdfile = self.merge2dtd(dtdtemplate, posource)
+ print dtdfile
+ assert str(dtdfile) == dtdexpected
+
+ def test_roundtrip_simple(self):
+ """checks that simple strings make it through a dtd->po->dtd roundtrip"""
+ self.check_roundtrip('"Hello"')
+ self.check_roundtrip('"Hello Everybody"')
+
+ def test_roundtrip_escape(self):
+ """checks that escapes in strings make it through a dtd->po->dtd roundtrip"""
+ self.check_roundtrip(r'"Simple Escape \ \n \\ \: \t \r "')
+ self.check_roundtrip(r'"End Line Escape \"')
+
+ def test_roundtrip_quotes(self):
+ """checks that (escaped) quotes in strings make it through a dtd->po->dtd roundtrip"""
+ self.check_roundtrip(r"""'Quote Escape "" '""")
+ self.check_roundtrip(r'''"Single-Quote ' "''')
+ self.check_roundtrip(r'''"Single-Quote Escape \' "''')
+ # NOTE: if both quote marks are present, than ' is converted to &apos;
+ self.check_roundtrip(r"""'Both Quotes "" &apos;&apos; '""")
+
+ def test_merging_entries_with_spaces_removed(self):
+ """dtd2po removes pretty printed spaces, this tests that we can merge this back into the pretty printed dtd"""
+ posource = '''#: simple.label\nmsgid "First line then "\n"next lines."\nmsgstr "Eerste lyne en dan volgende lyne."\n'''
+ dtdtemplate = '<!ENTITY simple.label "First line then\n' + \
+ ' next lines.">\n'
+ dtdexpected = '<!ENTITY simple.label "Eerste lyne en dan volgende lyne.">\n'
+ dtdfile = self.merge2dtd(dtdtemplate, posource)
+ print dtdfile
+ assert str(dtdfile) == dtdexpected
+
+ def test_comments(self):
+ """test that we preserve comments, bug 351"""
+ posource = '''#: name\nmsgid "Text"\nmsgstr "Teks"'''
+ dtdtemplate = '''<!ENTITY name "%s">\n<!-- \n\nexample -->\n'''
+ dtdfile = self.merge2dtd(dtdtemplate % "Text", posource)
+ print dtdfile
+ assert str(dtdfile) == dtdtemplate % "Teks"
+
+ def test_duplicates(self):
+ """test that we convert duplicates back correctly to their respective entries."""
+ posource = r'''#: bookmarksMenu.label bookmarksMenu.accesskey
+msgctxt "bookmarksMenu.label bookmarksMenu.accesskey"
+msgid "&Bookmarks"
+msgstr "Dipu&kutshwayo1"
+
+#: bookmarksItem.title
+msgctxt "bookmarksItem.title
+msgid "Bookmarks"
+msgstr "Dipukutshwayo2"
+
+#: bookmarksButton.label
+msgctxt "bookmarksButton.label"
+msgid "Bookmarks"
+msgstr "Dipukutshwayo3"
+'''
+ dtdtemplate = r'''<!ENTITY bookmarksMenu.label "Bookmarks">
+<!ENTITY bookmarksMenu.accesskey "B">
+<!ENTITY bookmarksItem.title "Bookmarks">
+<!ENTITY bookmarksButton.label "Bookmarks">
+'''
+ dtdexpected = r'''<!ENTITY bookmarksMenu.label "Dipukutshwayo1">
+<!ENTITY bookmarksMenu.accesskey "k">
+<!ENTITY bookmarksItem.title "Dipukutshwayo2">
+<!ENTITY bookmarksButton.label "Dipukutshwayo3">
+'''
+ dtdfile = self.merge2dtd(dtdtemplate, posource)
+ print dtdfile
+ assert str(dtdfile) == dtdexpected
+
+
+class TestPO2DTDCommand(test_convert.TestConvertCommand, TestPO2DTD):
+ """Tests running actual po2dtd commands on files"""
+ convertmodule = po2dtd
+ defaultoptions = {"progress": "none"}
+ # TODO: because of having 2 base classes, we need to call all their setup and teardown methods
+ # (otherwise we won't reset the warnings etc)
+ def setup_method(self, method):
+ """call both base classes setup_methods"""
+ test_convert.TestConvertCommand.setup_method(self, method)
+ TestPO2DTD.setup_method(self, method)
+ def teardown_method(self, method):
+ """call both base classes teardown_methods"""
+ test_convert.TestConvertCommand.teardown_method(self, method)
+ TestPO2DTD.teardown_method(self, method)
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "--fuzzy")
+ options = self.help_check(options, "--nofuzzy", last=True)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2html.py b/translate-toolkit-1.5.1/translate/convert/test_po2html.py
new file mode 100644
index 0000000..c7024c7
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2html.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+
+from translate.convert import po2html
+from translate.convert import test_convert
+from translate.misc import wStringIO
+
+class TestPO2Html:
+ def converthtml(self, posource, htmltemplate):
+ """helper to exercise the command line function"""
+ inputfile = wStringIO.StringIO(posource)
+ print inputfile.getvalue()
+ outputfile = wStringIO.StringIO()
+ templatefile = wStringIO.StringIO(htmltemplate)
+ assert po2html.converthtml(inputfile, outputfile, templatefile)
+ print outputfile.getvalue()
+ return outputfile.getvalue()
+
+ def test_simple(self):
+ """simple po to html test"""
+ htmlsource = '<p>A sentence.</p>'
+ posource = '''#: html:3\nmsgid "A sentence."\nmsgstr "'n Sin."\n'''
+ htmlexpected = '''<p>'n Sin.</p>'''
+ assert htmlexpected in self.converthtml(posource, htmlsource)
+
+ def test_linebreaks(self):
+ """Test that a po file can be merged into a template with linebreaks in it."""
+ htmlsource = '''<html>
+<head>
+</head>
+<body>
+<div>
+A paragraph is a section in a piece of writing, usually highlighting a
+particular point or topic. It always begins on a new line and usually
+with indentation, and it consists of at least one sentence.
+</div>
+</body>
+</html>
+'''
+ posource = '''#: None:1
+msgid ""
+"A paragraph is a section in a piece of writing, usually highlighting a "
+"particular point or topic. It always begins on a new line and usually with "
+"indentation, and it consists of at least one sentence."
+msgstr ""
+"'n Paragraaf is 'n afdeling in 'n geskrewe stuk wat gewoonlik 'n spesifieke "
+"punt uitlig. Dit begin altyd op 'n nuwe lyn (gewoonlik met indentasie) en "
+"dit bestaan uit ten minste een sin."
+'''
+ htmlexpected = '''<body>
+<div>
+'n Paragraaf is 'n afdeling in 'n geskrewe stuk wat gewoonlik
+'n spesifieke punt uitlig. Dit begin altyd op 'n nuwe lyn
+(gewoonlik met indentasie) en dit bestaan uit ten minste een
+sin.
+</div>
+</body>'''
+ assert htmlexpected.replace("\n", " ") in self.converthtml(posource, htmlsource).replace("\n", " ")
+
+ def xtest_entities(self):
+ """Tests that entities are handled correctly"""
+ htmlsource = '<p>5 less than 6</p>'
+ posource = '#:html:3\nmsgid "5 less than 6"\nmsgstr "5 < 6"\n'
+ htmlexpected = '<p>5 &lt; 6</p>'
+ assert htmlexpected in self.converthtml(posource, htmlsource)
+
+ htmlsource = '<p>Fish &amp; chips</p>'
+ posource = '#: html:3\nmsgid "Fish & chips"\nmsgstr "Vis & skyfies"\n'
+ htmlexpected = '<p>Vis &amp; skyfies</p>'
+ assert htmlexpected in self.converthtml(posource, htmlsource)
+
+ def xtest_escapes(self):
+ """Tests that PO escapes are correctly handled"""
+ htmlsource = '<div>Row 1<br />Row 2</div>'
+ posource = '#: html:3\nmsgid "Row 1\\n"\n"Row 2"\nmsgstr "Ry 1\\n"\n"Ry 2"\n'
+ htmlexpected = '<div>Ry 1<br />Ry 2</div>'
+ assert htmlexpected in self.converthtml(posource, htmlsource)
+
+ htmlsource = '<p>"leverage"</p>'
+ posource = '#: html3\nmsgid "\\"leverage\\""\nmsgstr "\\"ek is dom\\""\n'
+ htmlexpected = '<p>"ek is dom"</p>'
+ assert htmlexpected in self.converthtml(posource, htmlsource)
+
+
+class TestPO2HtmlCommand(test_convert.TestConvertCommand, TestPO2Html):
+ """Tests running actual po2oo commands on files"""
+ convertmodule = po2html
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "-w WRAP, --wrap=WRAP")
+ options = self.help_check(options, "--fuzzy")
+ options = self.help_check(options, "--nofuzzy", last=True)
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2moz.py b/translate-toolkit-1.5.1/translate/convert/test_po2moz.py
new file mode 100644
index 0000000..9c022f1
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2moz.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+from translate.convert import po2moz
+from translate.convert import test_convert
+
+class TestPO2Moz:
+ pass
+
+class TestPO2MozCommand(test_convert.TestConvertCommand, TestPO2Moz):
+ """Tests running actual po2moz commands on files"""
+ convertmodule = po2moz
+ defaultoptions = {"progress": "none"}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "-l LOCALE, --locale=LOCALE")
+ options = self.help_check(options, "--clonexpi=CLONEXPI")
+ options = self.help_check(options, "--fuzzy")
+ options = self.help_check(options, "--nofuzzy", last=True)
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2oo.py b/translate-toolkit-1.5.1/translate/convert/test_po2oo.py
new file mode 100644
index 0000000..15fcb45
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2oo.py
@@ -0,0 +1,182 @@
+#!/usr/bin/env python
+
+from translate.convert import po2oo
+from translate.convert import oo2po
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+import warnings
+import os
+
+class TestPO2OO:
+ def setup_method(self, method):
+ warnings.resetwarnings()
+
+ def teardown_method(self, method):
+ warnings.resetwarnings()
+
+ def convertoo(self, posource, ootemplate, language="en-US"):
+ """helper to exercise the command line function"""
+ inputfile = wStringIO.StringIO(posource)
+ outputfile = wStringIO.StringIO()
+ templatefile = wStringIO.StringIO(ootemplate)
+ assert po2oo.convertoo(inputfile, outputfile, templatefile, targetlanguage=language, timestamp=0)
+ return outputfile.getvalue()
+
+ def roundtripstring(self, entitystring):
+ oointro, oooutro = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US ', ' 2002-02-02 02:02:02' + '\r\n'
+ oosource = oointro + entitystring + oooutro
+ ooinputfile = wStringIO.StringIO(oosource)
+ ooinputfile2 = wStringIO.StringIO(oosource)
+ pooutputfile = wStringIO.StringIO()
+ oo2po.convertoo(ooinputfile, pooutputfile, ooinputfile2, targetlanguage='en-US')
+ posource = pooutputfile.getvalue()
+ poinputfile = wStringIO.StringIO(posource)
+ ootemplatefile = wStringIO.StringIO(oosource)
+ oooutputfile = wStringIO.StringIO()
+ po2oo.convertoo(poinputfile, oooutputfile, ootemplatefile, targetlanguage="en-US")
+ ooresult = oooutputfile.getvalue()
+ print "original oo:\n", oosource, "po version:\n", posource, "output oo:\n", ooresult
+ assert ooresult.startswith(oointro) and ooresult.endswith(oooutro)
+ return ooresult[len(oointro):-len(oooutro)]
+
+ def check_roundtrip(self, oosource):
+ """Checks that the round-tripped string is the same as the original"""
+ assert self.roundtripstring(oosource) == oosource
+
+ def test_convertoo(self):
+ """checks that the convertoo function is working"""
+ oobase = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 %s %s 20050924 09:13:58' + '\r\n'
+ posource = '''#: numpages.src#RID_SVXPAGE_NUM_OPTIONS.STR_BULLET.string.text\nmsgid "Simple String"\nmsgstr "Dimpled Ring"\n'''
+ ootemplate = oobase % ('en-US', 'Simple String')
+ ooexpected = oobase % ('zu', 'Dimpled Ring')
+ newoo = self.convertoo(posource, ootemplate, language="zu")
+ assert newoo == ootemplate + ooexpected
+
+ def test_pofilter(self):
+ """Tests integration with pofilter"""
+ #Some bad po with a few errors:
+ posource = '#: sourcefile.bla#ID_NUMBER.txet.gnirts\nmsgid "<tag cow=\\"3\\">Mistake."\nmsgstr " <etiket koei=\\"3\\">(fout) "'
+ filter = po2oo.filter
+ pofile = po.pofile()
+ pofile.parse(posource)
+ assert not filter.validelement(pofile.units[0], "dummyname.po", "exclude-all")
+
+ def test_roundtrip_simple(self):
+ """checks that simple strings make it through a oo->po->oo roundtrip"""
+ self.check_roundtrip('Hello')
+ self.check_roundtrip('"Hello"')
+ self.check_roundtrip('"Hello Everybody"')
+
+ def test_roundtrip_escape(self):
+ """checks that escapes in strings make it through a oo->po->oo roundtrip"""
+ self.check_roundtrip(r'"Simple Escape \ \n \\ \: \t \r "')
+ self.check_roundtrip(r'"More escapes \\n \\t \\r \\: "')
+ self.check_roundtrip(r'"More escapes \\\n \\\t \\\r \\\: "')
+ self.check_roundtrip(r'"More escapes \\\\n \\\\t \\\\r \\\\: "')
+ self.check_roundtrip(r'"End Line Escape \"')
+ self.check_roundtrip(r'"\\rangle \\langle')
+ self.check_roundtrip(r'\\\\<')
+ self.check_roundtrip(r'\\\<')
+ self.check_roundtrip(r'\\<')
+ self.check_roundtrip(r'\<')
+
+ def test_roundtrip_quotes(self):
+ """checks that (escaped) quotes in strings make it through a oo->po->oo roundtrip"""
+ self.check_roundtrip(r"""'Quote Escape "" '""")
+ self.check_roundtrip(r'''"Single-Quote ' "''')
+ self.check_roundtrip(r'''"Single-Quote Escape \' "''')
+ self.check_roundtrip(r"""'Both Quotes "" '' '""")
+
+ def xtest_roundtrip_spaces(self):
+ # FIXME: this test fails because the resultant PO file returns as po.isempty since .isblank returns true
+ # which is caused by isblankmsgtr returning True. Its a complete mess which would mean unravelling lots
+ # of yuch in pypo. Until we have time to do that unravelling we're diabling this test. You can reenable
+ # once we've fixed that.
+ """checks that (escaped) quotes in strings make it through a oo->po->oo roundtrip"""
+ self.check_roundtrip(" ")
+ self.check_roundtrip(u"\u00a0")
+
+ def test_default_timestamp(self):
+ """test to ensure that we revert to the default timestamp"""
+ oointro, oooutro = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US Text ', '\r\n'
+ posource = '''#: numpages.src#RID_SVXPAGE_NUM_OPTIONS.STR_BULLET.string.text\nmsgid "Text"\nmsgstr "Text"\n'''
+ inputfile = wStringIO.StringIO(posource)
+ outputfile = wStringIO.StringIO()
+ templatefile = wStringIO.StringIO(oointro + '20050924 09:13:58' + oooutro)
+ assert po2oo.convertoo(inputfile, outputfile, templatefile, targetlanguage="en-US")
+ assert outputfile.getvalue() == oointro + '2002-02-02 02:02:02' + oooutro
+
+ def test_escape_conversion(self):
+ """test to ensure that we convert escapes correctly"""
+ oosource = r'svx source\dialog\numpages.src 0 string RID_SVXPAGE_NUM_OPTIONS STR_BULLET 0 en-US Column1\tColumn2\r\n 2002-02-02 02:02:02' + '\r\n'
+ posource = '''#: numpages.src#RID_SVXPAGE_NUM_OPTIONS.STR_BULLET.string.text\nmsgid "Column1\\tColumn2\\r\\n"\nmsgstr "Kolom1\\tKolom2\\r\\n"\n'''
+ inputfile = wStringIO.StringIO(posource)
+ outputfile = wStringIO.StringIO()
+ templatefile = wStringIO.StringIO(oosource)
+ assert po2oo.convertoo(inputfile, outputfile, templatefile, targetlanguage="af-ZA")
+ assert "\tKolom1\\tKolom2\\r\\n\t" in outputfile.getvalue()
+
+ def test_helpcontent_escapes(self):
+ """test to ensure that we convert helpcontent escapes correctly"""
+ # Note how this test specifically uses incorrect spacing in the
+ # translation. The extra space before 'hid' and an extra space before
+ # the closing tag should not confuse us.
+ oosource = r'helpcontent2 source\text\shared\3dsettings_toolbar.xhp 0 help par_idN1056A 0 en-US \<ahelp hid=\".\"\>The 3D-Settings toolbar controls properties of selected 3D objects.\</ahelp\> 2002-02-02 02:02:02' + '\r\n'
+ posource = r'''#: 3dsettings_toolbar.xhp#par_idN1056A.help.text
+msgid ""
+"<ahelp hid=\".\">The 3D-Settings toolbar controls properties of selected 3D "
+"ob jects.</ahelp>"
+msgstr ""
+"<ahelp hid=\".\" >Zeee 3DDDD-Settings toolbar controls properties of selected 3D "
+"objects.</ahelp>"
+'''
+ inputfile = wStringIO.StringIO(posource)
+ outputfile = wStringIO.StringIO()
+ templatefile = wStringIO.StringIO(oosource)
+ assert po2oo.convertoo(inputfile, outputfile, templatefile, targetlanguage="af-ZA")
+ assert r"\<ahelp hid=\".\" \>Zeee 3DDDD-Settings toolbar controls properties of selected 3D objects.\</ahelp\>" in outputfile.getvalue()
+
+ def test_helpcontent_escapes2(self):
+ """test to ensure that we convert helpcontent escapes correctly"""
+ oosource = r'helpcontent2 source\text\scalc\05\empty_cells.xhp 0 help par_id2629474 0 en-US A1: <empty> 2002-02-02 02:02:02' + '\r\n'
+ posource = r'''#: empty_cells.xhp#par_id2629474.help.text
+msgid "A1: <empty>"
+msgstr "Aa1: <empty>"
+'''
+ inputfile = wStringIO.StringIO(posource)
+ outputfile = wStringIO.StringIO()
+ templatefile = wStringIO.StringIO(oosource)
+ assert po2oo.convertoo(inputfile, outputfile, templatefile, targetlanguage="af-ZA")
+ assert r"Aa1: <empty>" in outputfile.getvalue()
+
+class TestPO2OOCommand(test_convert.TestConvertCommand, TestPO2OO):
+ """Tests running actual po2oo commands on files"""
+ convertmodule = po2oo
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "--source-language=LANG")
+ options = self.help_check(options, "--language=LANG")
+ options = self.help_check(options, "-T, --keeptimestamp")
+ options = self.help_check(options, "--nonrecursiveoutput")
+ options = self.help_check(options, "--nonrecursivetemplate")
+ options = self.help_check(options, "--filteraction")
+ options = self.help_check(options, "--fuzzy")
+ options = self.help_check(options, "--nofuzzy")
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "--multifile=MULTIFILESTYLE", last=True)
+
+ def merge2oo(self, oosource, posource):
+ """helper that merges po translations to oo source through files"""
+ outputoo = convertor.convertstore(inputpo)
+ return outputoo
+
+ def convertoo(self, posource, ootemplate, language="en-US"):
+ """helper to exercise the command line function"""
+ self.create_testfile(os.path.join("input", "svx", "source", "dialog.po"), posource)
+ self.create_testfile("input.oo", ootemplate)
+ self.run_command("input", "output.oo", template="input.oo", language=language, keeptimestamp=True)
+ return self.read_testfile("output.oo")
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2php.py b/translate-toolkit-1.5.1/translate/convert/test_po2php.py
new file mode 100644
index 0000000..015549d
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2php.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import po2php
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+
+class TestPO2Php:
+ def po2php(self, posource):
+ """helper that converts po source to .php source without requiring files"""
+ inputfile = wStringIO.StringIO(posource)
+ inputpo = po.pofile(inputfile)
+ convertor = po2php.po2php()
+ outputphp = convertor.convertstore(inputpo)
+ return outputphp
+
+ def merge2php(self, phpsource, posource):
+ """helper that merges po translations to .php source without requiring files"""
+ inputfile = wStringIO.StringIO(posource)
+ inputpo = po.pofile(inputfile)
+ templatefile = wStringIO.StringIO(phpsource)
+ #templatephp = php.phpfile(templatefile)
+ convertor = po2php.rephp(templatefile)
+ outputphp = convertor.convertstore(inputpo)
+ print outputphp
+ return outputphp
+
+ def test_merging_simple(self):
+ """check the simplest case of merging a translation"""
+ posource = '''#: $lang['name']\nmsgid "value"\nmsgstr "waarde"\n'''
+ phptemplate = '''$lang['name'] = 'value';\n'''
+ phpexpected = '''$lang['name'] = 'waarde';\n'''
+ phpfile = self.merge2php(phptemplate, posource)
+ print phpfile
+ assert phpfile == [phpexpected]
+
+ def test_space_preservation(self):
+ """check that we preserve any spacing in php files when merging"""
+ posource = '''#: $lang['name']\nmsgid "value"\nmsgstr "waarde"\n'''
+ phptemplate = '''$lang['name'] = 'value';\n'''
+ phpexpected = '''$lang['name'] = 'waarde';\n'''
+ phpfile = self.merge2php(phptemplate, posource)
+ print phpfile
+ assert phpfile == [phpexpected]
+
+ def test_merging_blank_entries(self):
+ """check that we can correctly merge entries that are blank in the template"""
+ posource = r'''#: accesskey-accept
+msgid ""
+"_: accesskey-accept\n"
+""
+msgstr ""'''
+ phptemplate = '''$lang['accesskey-accept'] = '';\n'''
+ phpexpected = '''$lang['accesskey-accept'] = '';\n'''
+ phpfile = self.merge2php(phptemplate, posource)
+ print phpfile
+ assert phpfile == [phpexpected]
+
+ def test_merging_fuzzy(self):
+ """check merging a fuzzy translation"""
+ posource = '''#: $lang['name']\n#, fuzzy\nmsgid "value"\nmsgstr "waarde"\n'''
+ phptemplate = '''$lang['name'] = 'value';\n'''
+ phpexpected = '''$lang['name'] = 'value';\n'''
+ phpfile = self.merge2php(phptemplate, posource)
+ print phpfile
+ assert phpfile == [phpexpected]
+
+ def test_locations_with_spaces(self):
+ """check that a location with spaces in php but spaces removed in PO is used correctly"""
+ posource = '''#: $lang['name']\nmsgid "value"\nmsgstr "waarde"\n'''
+ phptemplate = '''$lang[ 'name' ] = 'value';\n'''
+ phpexpected = '''$lang[ 'name' ] = 'waarde';\n'''
+ phpfile = self.merge2php(phptemplate, posource)
+ print phpfile
+ assert phpfile == [phpexpected]
+
+ def test_inline_comments(self):
+ """check that we include inline comments from the template. Bug 590"""
+ posource = '''#: $lang['name']\nmsgid "value"\nmsgstr "waarde"\n'''
+ phptemplate = '''$lang[ 'name' ] = 'value'; //inline comment\n'''
+ phpexpected = '''$lang[ 'name' ] = 'waarde'; //inline comment\n'''
+ phpfile = self.merge2php(phptemplate, posource)
+ print phpfile
+ assert phpfile == [phpexpected]
+
+ def test_named_variables(self):
+ """check that we convert correctly if using named variables."""
+ posource = '''#: $dictYear
+msgid "Year"
+msgstr "Jaar"
+'''
+ phptemplate = '''$dictYear = 'Year';\n'''
+ phpexpected = '''$dictYear = 'Jaar';\n'''
+ phpfile = self.merge2php(phptemplate, posource)
+ print phpfile
+ assert phpfile == [phpexpected]
+
+# def test_merging_propertyless_template(self):
+# """check that when merging with a template with no property values that we copy the template"""
+# posource = ""
+# proptemplate = "# A comment\n"
+# propexpected = proptemplate
+# propfile = self.merge2prop(proptemplate, posource)
+# print propfile
+# assert propfile == [propexpected]
+
+class TestPO2PhpCommand(test_convert.TestConvertCommand, TestPO2Php):
+ """Tests running actual po2php commands on files"""
+ convertmodule = po2php
+ defaultoptions = {"progress": "none"}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "--fuzzy")
+ options = self.help_check(options, "--nofuzzy", last=True)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2prop.py b/translate-toolkit-1.5.1/translate/convert/test_po2prop.py
new file mode 100644
index 0000000..e590608
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2prop.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import po2prop
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+
+class TestPO2Prop:
+ def po2prop(self, posource):
+ """helper that converts po source to .properties source without requiring files"""
+ inputfile = wStringIO.StringIO(posource)
+ inputpo = po.pofile(inputfile)
+ convertor = po2prop.po2prop()
+ outputprop = convertor.convertstore(inputpo)
+ return outputprop
+
+ def merge2prop(self, propsource, posource, personality="java"):
+ """helper that merges po translations to .properties source without requiring files"""
+ inputfile = wStringIO.StringIO(posource)
+ inputpo = po.pofile(inputfile)
+ templatefile = wStringIO.StringIO(propsource)
+ #templateprop = properties.propfile(templatefile)
+ convertor = po2prop.reprop(templatefile)
+ outputprop = convertor.convertstore(inputpo, personality=personality)
+ print outputprop
+ return outputprop
+
+ def test_merging_simple(self):
+ """check the simplest case of merging a translation"""
+ posource = '''#: prop\nmsgid "value"\nmsgstr "waarde"\n'''
+ proptemplate = '''prop=value\n'''
+ propexpected = '''prop=waarde\n'''
+ propfile = self.merge2prop(proptemplate, posource)
+ print propfile
+ assert propfile == [propexpected]
+
+ def test_hard_newlines_preserved(self):
+ """check that we preserver hard coded newlines at the start and end of sentence"""
+ posource = '''#: prop\nmsgid "\\nvalue\\n\\n"\nmsgstr "\\nwaarde\\n\\n"\n'''
+ proptemplate = '''prop=\\nvalue\\n\\n\n'''
+ propexpected = '''prop=\\nwaarde\\n\\n\n'''
+ propfile = self.merge2prop(proptemplate, posource)
+ print propfile
+ assert propfile == [propexpected]
+
+ def test_space_preservation(self):
+ """check that we preserve any spacing in properties files when merging"""
+ posource = '''#: prop\nmsgid "value"\nmsgstr "waarde"\n'''
+ proptemplate = '''prop = value\n'''
+ propexpected = '''prop = waarde\n'''
+ propfile = self.merge2prop(proptemplate, posource)
+ print propfile
+ assert propfile == [propexpected]
+
+ def test_merging_blank_entries(self):
+ """check that we can correctly merge entries that are blank in the template"""
+ posource = r'''#: accesskey-accept
+msgid ""
+"_: accesskey-accept\n"
+""
+msgstr ""'''
+ proptemplate = 'accesskey-accept=\n'
+ propexpected = 'accesskey-accept=\n'
+ propfile = self.merge2prop(proptemplate, posource)
+ print propfile
+ assert propfile == [propexpected]
+
+ def test_merging_fuzzy(self):
+ """check merging a fuzzy translation"""
+ posource = '''#: prop\n#, fuzzy\nmsgid "value"\nmsgstr "waarde"\n'''
+ proptemplate = '''prop=value\n'''
+ propexpected = '''prop=value\n'''
+ propfile = self.merge2prop(proptemplate, posource)
+ print propfile
+ assert propfile == [propexpected]
+
+ def test_merging_propertyless_template(self):
+ """check that when merging with a template with no property values that we copy the template"""
+ posource = ""
+ proptemplate = "# A comment\n"
+ propexpected = proptemplate
+ propfile = self.merge2prop(proptemplate, posource)
+ print propfile
+ assert propfile == [propexpected]
+
+ def test_personalities(self):
+ """test that we output correctly for Java and Mozilla style property files. Mozilla uses Unicode, while Java uses escaped Unicode"""
+ posource = '''#: prop\nmsgid "value"\nmsgstr "ṽḁḽṻḝ"\n'''
+ proptemplate = '''prop = value\n'''
+ propexpectedjava = '''prop = \\u1E7D\\u1E01\\u1E3D\\u1E7B\\u1E1D\n'''
+ propfile = self.merge2prop(proptemplate, posource)
+ print propfile
+ assert propfile == [propexpectedjava]
+ propexpectedmozilla = '''prop = ṽḁḽṻḝ\n'''
+ propfile = self.merge2prop(proptemplate, posource, personality="mozilla")
+ print propfile
+ assert propfile == [propexpectedmozilla]
+
+class TestPO2PropCommand(test_convert.TestConvertCommand, TestPO2Prop):
+ """Tests running actual po2prop commands on files"""
+ convertmodule = po2prop
+ defaultoptions = {"progress": "none"}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "--fuzzy")
+ options = self.help_check(options, "--personality=TYPE")
+ options = self.help_check(options, "--nofuzzy", last=True)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2tiki.py b/translate-toolkit-1.5.1/translate/convert/test_po2tiki.py
new file mode 100644
index 0000000..6041393
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2tiki.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# po2tiki unit tests
+# Author: Wil Clouser <wclouser@mozilla.com>
+# Date: 2008-12-01
+
+from translate.convert import po2tiki
+from translate.storage import tiki
+from translate.convert import test_convert
+from translate.misc import wStringIO
+
+class TestPo2Tiki:
+ def test_convertpo(self):
+ inputfile = """
+#: translated
+msgid "zero_source"
+msgstr "zero_target"
+
+#: unused
+msgid "one_source"
+msgstr "one_target"
+ """
+ outputfile = wStringIO.StringIO()
+ po2tiki.convertpo(inputfile, outputfile)
+
+ output = outputfile.getvalue()
+
+ assert '"one_source" => "one_target",' in output
+ assert '"zero_source" => "zero_target",' in output
+
+
+class TestPo2TikiCommand(test_convert.TestConvertCommand, TestPo2Tiki):
+ """Tests running actual po2tiki commands on files"""
+ convertmodule = po2tiki
+ defaultoptions = {}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2tmx.py b/translate-toolkit-1.5.1/translate/convert/test_po2tmx.py
new file mode 100644
index 0000000..a13d5d5
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2tmx.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import po2tmx
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import tmx
+from translate.storage import lisa
+
+class TestPO2TMX:
+
+ def po2tmx(self, posource, sourcelanguage='en', targetlanguage='af'):
+ """helper that converts po source to tmx source without requiring files"""
+ inputfile = wStringIO.StringIO(posource)
+ outputfile = wStringIO.StringIO()
+ outputfile.tmxfile = tmx.tmxfile(inputfile=None, sourcelanguage=sourcelanguage)
+ po2tmx.convertpo(inputfile, outputfile, templatefile=None, sourcelanguage=sourcelanguage, targetlanguage=targetlanguage)
+ return outputfile.tmxfile
+
+ def test_basic(self):
+ minipo = """# Afrikaans translation of program ABC
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: program 2.1-branch\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2006-01-09 07:15+0100\n"
+"PO-Revision-Date: 2004-03-30 17:02+0200\n"
+"Last-Translator: Zuza Software Foundation <xxx@translate.org.za>\n"
+"Language-Team: Afrikaans <translate-discuss-xxx@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+# Please remember to do something
+#: ../dir/file.xml.in.h:1 ../dir/file2.xml.in.h:4
+msgid "Applications"
+msgstr "Toepassings"
+"""
+ tmx = self.po2tmx(minipo)
+ print "The generated xml:"
+ print str(tmx)
+ assert tmx.translate("Applications") == "Toepassings"
+ assert tmx.translate("bla") is None
+ xmltext = str(tmx)
+ assert xmltext.index('creationtool="Translate Toolkit - po2tmx"')
+ assert xmltext.index('adminlang')
+ assert xmltext.index('creationtoolversion')
+ assert xmltext.index('datatype')
+ assert xmltext.index('o-tmf')
+ assert xmltext.index('segtype')
+ assert xmltext.index('srclang')
+
+ def test_sourcelanguage(self):
+ minipo = 'msgid "String"\nmsgstr "String"\n'
+ tmx = self.po2tmx(minipo, sourcelanguage="xh")
+ print "The generated xml:"
+ print str(tmx)
+ header = tmx.document.find("header")
+ assert header.get("srclang") == "xh"
+
+ def test_targetlanguage(self):
+ minipo = 'msgid "String"\nmsgstr "String"\n'
+ tmx = self.po2tmx(minipo, targetlanguage="xh")
+ print "The generated xml:"
+ print str(tmx)
+ tuv = tmx.document.findall(".//%s" % tmx.namespaced("tuv"))[1]
+ #tag[0] will be the source, we want the target tuv
+ assert tuv.get("{%s}lang" % lisa.XML_NS) == "xh"
+
+ def test_multiline(self):
+ """Test multiline po entry"""
+ minipo = r'''msgid "First part "
+"and extra"
+msgstr "Eerste deel "
+"en ekstra"'''
+ tmx = self.po2tmx(minipo)
+ print "The generated xml:"
+ print str(tmx)
+ assert tmx.translate('First part and extra') == 'Eerste deel en ekstra'
+
+
+ def test_escapednewlines(self):
+ """Test the escaping of newlines"""
+ minipo = r'''msgid "First line\nSecond line"
+msgstr "Eerste lyn\nTweede lyn"
+'''
+ tmx = self.po2tmx(minipo)
+ print "The generated xml:"
+ print str(tmx)
+ assert tmx.translate("First line\nSecond line") == "Eerste lyn\nTweede lyn"
+
+ def test_escapedtabs(self):
+ """Test the escaping of tabs"""
+ minipo = r'''msgid "First column\tSecond column"
+msgstr "Eerste kolom\tTweede kolom"
+'''
+ tmx = self.po2tmx(minipo)
+ print "The generated xml:"
+ print str(tmx)
+ assert tmx.translate("First column\tSecond column") == "Eerste kolom\tTweede kolom"
+
+ def test_escapedquotes(self):
+ """Test the escaping of quotes (and slash)"""
+ minipo = r'''msgid "Hello \"Everyone\""
+msgstr "Good day \"All\""
+
+msgid "Use \\\"."
+msgstr "Gebruik \\\"."
+'''
+ tmx = self.po2tmx(minipo)
+ print "The generated xml:"
+ print str(tmx)
+ assert tmx.translate('Hello "Everyone"') == 'Good day "All"'
+ assert tmx.translate(r'Use \".') == r'Gebruik \".'
+
+ def test_exclusions(self):
+ """Test that empty and fuzzy messages are excluded"""
+ minipo = r'''#, fuzzy
+msgid "One"
+msgstr "Een"
+
+msgid "Two"
+msgstr ""
+
+msgid ""
+msgstr "Drie"
+'''
+ tmx = self.po2tmx(minipo)
+ print "The generated xml:"
+ print str(tmx)
+ assert "<tu" not in str(tmx)
+ assert len(tmx.units) == 0
+
+ def test_nonascii(self):
+ """Tests that non-ascii conversion works."""
+ minipo = r'''msgid "Bézier curve"
+msgstr "Bézier-kurwe"
+'''
+ tmx = self.po2tmx(minipo)
+ print str(tmx)
+ assert tmx.translate(u"Bézier curve") == u"Bézier-kurwe"
+
+
+class TestPO2TMXCommand(test_convert.TestConvertCommand, TestPO2TMX):
+ """Tests running actual po2tmx commands on files"""
+ convertmodule = po2tmx
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-l LANG, --language=LANG")
+ options = self.help_check(options, "--source-language=LANG", last=True)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2ts.py b/translate-toolkit-1.5.1/translate/convert/test_po2ts.py
new file mode 100644
index 0000000..7213a48
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2ts.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+
+from translate.convert import po2ts
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+
+class TestPO2TS:
+ def po2ts(self, posource):
+ """helper that converts po source to ts source without requiring files"""
+ inputfile = wStringIO.StringIO(posource)
+ inputpo = po.pofile(inputfile)
+ convertor = po2ts.po2ts()
+ outputts = convertor.convertstore(inputpo)
+ return outputts
+
+ def singleelement(self, storage):
+ """checks that the pofile contains a single non-header element, and returns it"""
+ assert len(storage.units) == 1
+ return storage.units[0]
+
+ def test_simpleunit(self):
+ """checks that a simple po entry definition converts properly to a ts entry"""
+ minipo = r'''#: term.cpp
+msgid "Term"
+msgstr "asdf"'''
+ tsfile = self.po2ts(minipo)
+ print tsfile
+ assert "<name>term.cpp</name>" in tsfile
+ assert "<source>Term</source>" in tsfile
+ assert "<translation>asdf</translation>" in tsfile
+ assert "<comment>" not in tsfile
+
+ def test_fullunit(self):
+ """check that an entry with various settings is converted correctly"""
+ posource = '''# Translator comment
+#. Automatic comment
+#: location.cpp:100
+msgid "Source"
+msgstr "Target"
+'''
+ tsfile = self.po2ts(posource)
+ print tsfile
+ # The other section are a duplicate of test_simplentry
+ # FIXME need to think about auto vs trans comments maybe in TS v1.1
+ assert "<comment>Translator comment</comment>" in tsfile
+
+ def test_fuzzyunit(self):
+ """check that we handle fuzzy units correctly"""
+ posource = '''#: term.cpp
+#, fuzzy
+msgid "Source"
+msgstr "Target"'''
+ tsfile = self.po2ts(posource)
+ print tsfile
+ assert '''<translation type="unfinished">Target</translation>''' in tsfile
+
+ def test_obsolete(self):
+ """test that we can take back obsolete messages"""
+ posource = '''#. (obsolete)
+#: term.cpp
+msgid "Source"
+msgstr "Target"'''
+ tsfile = self.po2ts(posource)
+ print tsfile
+ assert '''<translation type="obsolete">Target</translation>''' in tsfile
+
+ def test_duplicates(self):
+ """test that we can handle duplicates in the same context block"""
+ posource = '''#: @@@#1
+msgid "English"
+msgstr "a"
+
+#: @@@#3
+msgid "English"
+msgstr "b"
+'''
+ tsfile = self.po2ts(posource)
+ print tsfile
+ assert tsfile.find("English") != tsfile.rfind("English")
+
+
+class TestPO2TSCommand(test_convert.TestConvertCommand, TestPO2TS):
+ """Tests running actual po2ts commands on files"""
+ convertmodule = po2ts
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-c CONTEXT, --context=CONTEXT")
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE", last=True)
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2txt.py b/translate-toolkit-1.5.1/translate/convert/test_po2txt.py
new file mode 100644
index 0000000..20e8451
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2txt.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import po2txt
+from translate.convert import test_convert
+from translate.misc import wStringIO
+
+class TestPO2Txt:
+ def po2txt(self, posource, txttemplate=None):
+ """helper that converts po source to txt source without requiring files"""
+ inputfile = wStringIO.StringIO(posource)
+ print inputfile.getvalue()
+ outputfile = wStringIO.StringIO()
+ if txttemplate:
+ templatefile = wStringIO.StringIO(txttemplate)
+ else:
+ templatefile = None
+ assert po2txt.converttxt(inputfile, outputfile, templatefile)
+ print outputfile.getvalue()
+ return outputfile.getvalue()
+
+ def test_basic(self):
+ """test basic conversion"""
+ txttemplate = "Heading\n\nBody text"
+ posource = 'msgid "Heading"\nmsgstr "Opskrif"\n\nmsgid "Body text"\nmsgstr "Lyfteks"\n'
+ assert self.po2txt(posource, txttemplate) == "Opskrif\n\nLyfteks"
+
+ def test_nonascii(self):
+ """test conversion with non-ascii text"""
+ txttemplate = "Heading\n\nFile content"
+ posource = 'msgid "Heading"\nmsgstr "Opskrif"\n\nmsgid "File content"\nmsgstr "Lêerinhoud"\n'
+ assert self.po2txt(posource, txttemplate) == "Opskrif\n\nLêerinhoud"
+
+ def test_blank_handling(self):
+ """check that we discard blank messages"""
+ txttemplate = "Heading\n\nBody text"
+ posource = 'msgid "Heading"\nmsgstr "Opskrif"\n\nmsgid "Body text"\nmsgstr ""\n'
+ assert self.po2txt(posource) == "Opskrif\n\nBody text"
+ assert self.po2txt(posource, txttemplate) == "Opskrif\n\nBody text"
+
+ def test_fuzzy_handling(self):
+ """check that we handle fuzzy message correctly"""
+ txttemplate = "Heading\n\nBody text"
+ posource = '#, fuzzy\nmsgid "Heading"\nmsgstr "Opskrif"\n\nmsgid "Body text"\nmsgstr "Lyfteks"\n'
+ assert self.po2txt(posource) == "Heading\n\nLyfteks"
+ assert self.po2txt(posource, txttemplate) == "Heading\n\nLyfteks"
+
+class TestPO2TxtCommand(test_convert.TestConvertCommand, TestPO2Txt):
+ """Tests running actual po2txt commands on files"""
+ convertmodule = po2txt
+ defaultoptions = {"progress": "none"}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "--fuzzy")
+ options = self.help_check(options, "--nofuzzy")
+ options = self.help_check(options, "--encoding")
+ options = self.help_check(options, "-w WRAP, --wrap=WRAP", last=True)
diff --git a/translate-toolkit-1.5.1/translate/convert/test_po2xliff.py b/translate-toolkit-1.5.1/translate/convert/test_po2xliff.py
new file mode 100644
index 0000000..1ee0555
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_po2xliff.py
@@ -0,0 +1,296 @@
+#!/usr/bin/env python
+
+from translate.convert import po2xliff
+from translate.storage import po
+from translate.storage import poxliff
+from translate.storage import lisa
+
+class TestPO2XLIFF:
+
+ def po2xliff(self, posource, sourcelanguage='en', targetlanguage=None):
+ """helper that converts po source to xliff source without requiring files"""
+ postore = po.pofile(posource)
+ convertor = po2xliff.po2xliff()
+ outputxliff = convertor.convertstore(postore, None, sourcelanguage=sourcelanguage, targetlanguage=targetlanguage)
+ return poxliff.PoXliffFile(outputxliff)
+
+ def getnode(self, xliff):
+ """Retrieves the trans-unit node from the dom"""
+ assert len(xliff.units) == 1
+ unit = xliff.units[0]
+ return unit
+
+ def test_minimal(self):
+ minipo = '''msgid "red"\nmsgstr "rooi"\n'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ print str(xliff)
+ assert len(xliff.units) == 1
+ assert xliff.translate("red") == "rooi"
+ assert xliff.translate("bla") is None
+
+ def test_basic(self):
+ minipo = """# Afrikaans translation of program ABC
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: program 2.1-branch\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2006-01-09 07:15+0100\n"
+"PO-Revision-Date: 2004-03-30 17:02+0200\n"
+"Last-Translator: Zuza Software Foundation <xxx@translate.org.za>\n"
+"Language-Team: Afrikaans <translate-discuss-xxx@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+# Please remember to do something
+#: ../dir/file.xml.in.h:1 ../dir/file2.xml.in.h:4
+msgid "Applications"
+msgstr "Toepassings"
+"""
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ print str(xliff)
+ assert xliff.translate("Applications") == "Toepassings"
+ assert xliff.translate("bla") is None
+ xmltext = str(xliff)
+ assert xmltext.index('<xliff ') >= 0
+ assert xmltext.index(' version="1.1"') >= 0
+ assert xmltext.index('<file')
+ assert xmltext.index('source-language')
+ assert xmltext.index('datatype')
+
+ def test_multiline(self):
+ """Test multiline po entry"""
+ minipo = r'''msgid "First part "
+"and extra"
+msgstr "Eerste deel "
+"en ekstra"'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ print str(xliff)
+ assert xliff.translate('First part and extra') == 'Eerste deel en ekstra'
+
+
+ def test_escapednewlines(self):
+ """Test the escaping of newlines"""
+ minipo = r'''msgid "First line\nSecond line"
+msgstr "Eerste lyn\nTweede lyn"
+'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ xmltext = str(xliff)
+ print xmltext
+ assert xliff.translate("First line\nSecond line") == "Eerste lyn\nTweede lyn"
+ assert xliff.translate("First line\\nSecond line") is None
+ assert xmltext.find("line\\nSecond") == -1
+ assert xmltext.find("lyn\\nTweede") == -1
+ assert xmltext.find("line\nSecond") > 0
+ assert xmltext.find("lyn\nTweede") > 0
+
+ def test_escapedtabs(self):
+ """Test the escaping of tabs"""
+ minipo = r'''msgid "First column\tSecond column"
+msgstr "Eerste kolom\tTweede kolom"
+'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ xmltext = str(xliff)
+ print xmltext
+ assert xliff.translate("First column\tSecond column") == "Eerste kolom\tTweede kolom"
+ assert xliff.translate("First column\\tSecond column") is None
+ assert xmltext.find("column\\tSecond") == -1
+ assert xmltext.find("kolom\\tTweede") == -1
+ assert xmltext.find("column\tSecond") > 0
+ assert xmltext.find("kolom\tTweede") > 0
+
+ def test_escapedquotes(self):
+ """Test the escaping of quotes (and slash)"""
+ minipo = r'''msgid "Hello \"Everyone\""
+msgstr "Good day \"All\""
+
+msgid "Use \\\"."
+msgstr "Gebruik \\\"."
+'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ xmltext = str(xliff)
+ print xmltext
+ assert xliff.translate('Hello "Everyone"') == 'Good day "All"'
+ assert xliff.translate(r'Use \".') == r'Gebruik \".'
+ assert xmltext.find(r'\&quot;') > 0 or xmltext.find(r'\"') > 0
+ assert xmltext.find(r"\\") == -1
+
+ def getcontexttuples(self, node, namespace):
+ """Returns all the information in the context nodes as a list of tuples
+ of (type, text)"""
+ contexts = node.findall(".//{%s}context" % namespace)
+ return [(context.get("context-type"), lisa.getText(context)) for context in contexts]
+
+ def test_locationcomments(self):
+ minipo = r'''#: file.c:123 asdf.c
+msgid "one"
+msgstr "kunye"
+'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ xmltext = str(xliff)
+ print xmltext
+ assert xliff.translate("one") == "kunye"
+ assert len(xliff.units) == 1
+ node = xliff.units[0].xmlelement
+ contextgroups = node.findall(".//%s" % xliff.namespaced("context-group"))
+ assert len(contextgroups) == 2
+ for group in contextgroups:
+ assert group.get("name") == "po-reference"
+ assert group.get("purpose") == "location"
+ tuples = self.getcontexttuples(node, xliff.namespace)
+ assert tuples == [("sourcefile", "file.c"), ("linenumber", "123"), ("sourcefile", "asdf.c")]
+
+ def test_othercomments(self):
+ minipo = r'''# Translate?
+# How?
+msgid "one"
+msgstr "kunye"
+'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ xmltext = str(xliff)
+ print xmltext
+ assert xliff.translate("one") == "kunye"
+ assert len(xliff.units) == 1
+ node = xliff.units[0].xmlelement
+ contextgroups = node.findall(".//%s" % xliff.namespaced("context-group"))
+ assert len(contextgroups) == 1
+ for group in contextgroups:
+ assert group.get("name") == "po-entry"
+ assert group.get("purpose") == "information"
+ tuples = self.getcontexttuples(node, xliff.namespace)
+ assert tuples == [("x-po-trancomment", "Translate?\nHow?")]
+
+ assert xliff.units[0].getnotes("translator") == "Translate?\nHow?"
+
+
+ def test_automaticcomments(self):
+ minipo = r'''#. Don't translate.
+#. Please
+msgid "one"
+msgstr "kunye"
+'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ xmltext = str(xliff)
+ print xmltext
+ assert xliff.translate("one") == "kunye"
+ assert len(xliff.units) == 1
+ node = xliff.units[0].xmlelement
+ contextgroups = node.findall(".//%s" % xliff.namespaced("context-group"))
+ assert len(contextgroups) == 1
+ for group in contextgroups:
+ assert group.get("name") == "po-entry"
+ assert group.get("purpose") == "information"
+ tuples = self.getcontexttuples(node, xliff.namespace)
+ assert tuples == [("x-po-autocomment", "Don't translate.\nPlease")]
+
+ def test_header(self):
+ minipo = r'''# Pulana Translation for bla
+# Hallo Ma!
+#, fuzzy
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ xmltext = str(xliff)
+ print xmltext
+ assert len(xliff.units) == 1
+ unit = xliff.units[0]
+ assert unit.source == unit.target == "MIME-Version: 1.0\n"
+ assert unit.xmlelement.get("restype") == "x-gettext-domain-header"
+ assert unit.xmlelement.get("approved") != "yes"
+ assert unit.xmlelement.get("{%s}space" % lisa.XML_NS) == "preserve"
+ assert unit.getnotes("po-translator") == "Pulana Translation for bla\nHallo Ma!"
+
+ def test_fuzzy(self):
+ minipo = r'''#, fuzzy
+msgid "two"
+msgstr "pedi"
+
+msgid "three"
+msgstr "raro"
+'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ xmltext = str(xliff)
+ print xmltext
+ assert len(xliff.units) == 2
+ assert xliff.units[0].isfuzzy()
+ assert not xliff.units[1].isfuzzy()
+
+ def test_germanic_plurals(self):
+ minipo = r'''msgid "cow"
+msgid_plural "cows"
+msgstr[0] "inkomo"
+msgstr[1] "iinkomo"
+'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ xmltext = str(xliff)
+ print xmltext
+ assert len(xliff.units) == 1
+ assert xliff.translate("cow") == "inkomo"
+
+ def test_funny_plurals(self):
+ minipo = r'''msgid "cow"
+msgid_plural "cows"
+msgstr[0] "inkomo"
+msgstr[1] "iinkomo"
+msgstr[2] "iiinkomo"
+'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ xmltext = str(xliff)
+ print xmltext
+ assert len(xliff.units) == 1
+ assert xliff.translate("cow") == "inkomo"
+
+ def test_language_tags(self):
+ minipo = r'''msgid "Een"
+msgstr "Uno"
+'''
+ xliff = self.po2xliff(minipo, "af", "es")
+ assert xliff.sourcelanguage == "af"
+ assert xliff.targetlanguage == "es"
+
+ def test_variables(self):
+ minipo = r'''msgid "%s%s%s%s has made %s his or her buddy%s%s"
+msgstr "%s%s%s%s het %s sy/haar vriend/vriendin gemaak%s%s"'''
+ xliff = self.po2xliff(minipo)
+ print xliff.units[0].source
+ assert xliff.units[0].source == "%s%s%s%s has made %s his or her buddy%s%s"
+
+ def test_approved(self):
+ minipo = r'''#, fuzzy
+msgid "two"
+msgstr "pedi"
+
+msgid "three"
+msgstr "raro"
+
+msgid "four"
+msgstr ""
+'''
+ xliff = self.po2xliff(minipo)
+ print "The generated xml:"
+ xmltext = str(xliff)
+ print xmltext
+ assert len(xliff.units) == 3
+ assert xliff.units[0].xmlelement.get("approved") != "yes"
+ assert not xliff.units[0].isapproved()
+ assert xliff.units[1].xmlelement.get("approved") == "yes"
+ assert xliff.units[1].isapproved()
+ assert xliff.units[2].xmlelement.get("approved") != "yes"
+ assert not xliff.units[2].isapproved()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_pot2po.py b/translate-toolkit-1.5.1/translate/convert/test_pot2po.py
new file mode 100644
index 0000000..5404449
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_pot2po.py
@@ -0,0 +1,609 @@
+#!/usr/bin/env python
+
+from translate.convert import pot2po
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+import warnings
+
+class TestPOT2PO:
+ def setup_method(self, method):
+ warnings.resetwarnings()
+
+ def teardown_method(self, method):
+ warnings.resetwarnings()
+
+ def convertpot(self, potsource, posource=None):
+ """helper that converts pot source to po source without requiring files"""
+ potfile = wStringIO.StringIO(potsource)
+ if posource:
+ pofile = wStringIO.StringIO(posource)
+ else:
+ pofile = None
+ pooutfile = wStringIO.StringIO()
+ pot2po.convertpot(potfile, pooutfile, pofile)
+ pooutfile.seek(0)
+ return po.pofile(pooutfile.read())
+
+ def singleunit(self, pofile):
+ """checks that the pofile contains a single non-header unit, and returns it"""
+ assert len(pofile.units) == 2
+ assert pofile.units[0].isheader()
+ print pofile.units[1]
+ return pofile.units[1]
+
+ def test_convertpot_blank(self):
+ """checks that the convertpot function is working for a simple file initialisation"""
+ potsource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep
+ newpo = self.convertpot(potsource)
+ assert str(self.singleunit(newpo)) == potsource
+
+ def test_convertpot_blank_plurals(self):
+ """checks that the convertpot function is working for initialising plurals correctly"""
+ potsource = r'''msgid ""
+msgstr""
+
+msgid "%d manual"
+msgid_plural "%d manuals"
+msgstr[0] ""
+msgstr[1] ""
+'''
+ posource = r'''msgid ""
+msgstr""
+"Plural-Forms: nplurals=1; plural=0;\n"
+'''
+
+ poexpected = r'''msgid "%d manual"
+msgid_plural "%d manuals"
+msgstr[0] ""
+'''
+ newpo = self.convertpot(potsource, posource)
+ assert str(self.singleunit(newpo)) == poexpected
+
+ def test_merging_simple(self):
+ """checks that the convertpot function is working for a simple merge"""
+ potsource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep
+ posource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep
+ newpo = self.convertpot(potsource, posource)
+ assert str(self.singleunit(newpo)) == posource
+
+ def test_merging_messages_marked_fuzzy(self):
+ """test that when we merge PO files with a fuzzy message that it remains fuzzy"""
+ potsource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep
+ posource = '''#: simple.label%ssimple.accesskey\n#, fuzzy\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep
+ newpo = self.convertpot(potsource, posource)
+ assert str(self.singleunit(newpo)) == posource
+
+ def test_merging_plurals_with_fuzzy_matching(self):
+ """test that when we merge PO files with a fuzzy message that it remains fuzzy"""
+ potsource = r'''#: file.cpp:2
+msgid "%d manual"
+msgid_plural "%d manuals"
+msgstr[0] ""
+msgstr[1] ""
+'''
+ posource = r'''#: file.cpp:3
+#, fuzzy
+msgid "%d manual"
+msgid_plural "%d manuals"
+msgstr[0] "%d handleiding."
+msgstr[1] "%d handleidings."
+'''
+ # The #: comment and msgid's are different between the pot and the po
+ poexpected = r'''#: file.cpp:2
+#, fuzzy
+msgid "%d manual"
+msgid_plural "%d manuals"
+msgstr[0] "%d handleiding."
+msgstr[1] "%d handleidings."
+'''
+ newpo = self.convertpot(potsource, posource)
+ assert str(self.singleunit(newpo)) == poexpected
+
+ def xtest_merging_msgid_change(self):
+ """tests that if the msgid changes but the location stays the same that we merge"""
+ potsource = '''#: simple.label\n#: simple.accesskey\nmsgid "Its &hard coding a newline.\\n"\nmsgstr ""\n'''
+ posource = '''#: simple.label\n#: simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n'''
+ poexpected = '''#: simple.label\n#: simple.accesskey\n#, fuzzy\nmsgid "Its &hard coding a newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n'''
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ assert str(self.singleunit(newpo)) == poexpected
+
+ def test_merging_location_change(self):
+ """tests that if the location changes but the msgid stays the same that we merge"""
+ potsource = '''#: new_simple.label%snew_simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep
+ posource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep
+ poexpected = '''#: new_simple.label%snew_simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ assert str(self.singleunit(newpo)) == poexpected
+
+ def test_merging_location_and_whitespace_change(self):
+ """test that even if the location changes that if the msgid only has whitespace changes we can still merge"""
+ potsource = '''#: singlespace.label%ssinglespace.accesskey\nmsgid "&We have spaces"\nmsgstr ""\n''' % po.lsep
+ posource = '''#: doublespace.label%sdoublespace.accesskey\nmsgid "&We have spaces"\nmsgstr "&One het spasies"\n''' % po.lsep
+ poexpected = '''#: singlespace.label%ssinglespace.accesskey\n#, fuzzy\nmsgid "&We have spaces"\nmsgstr "&One het spasies"\n''' % po.lsep
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ assert str(self.singleunit(newpo)) == poexpected
+
+ def test_merging_location_ambiguous_with_disambiguous(self):
+ """test that when we have a PO in ambiguous (Gettext form) and merge with disamabiguous (KDE comment form)
+ that we don't duplicate the location #: comments"""
+ potsource = '''#: location.c:1\nmsgid ""\n"_: location.c:1\\n"\n"Source"\nmsgstr ""\n\n''' + \
+ '''#: location.c:10\nmsgid ""\n"_: location.c:10\\n"\n"Source"\nmsgstr ""\n'''
+ posource = '''#: location.c:1\n#: location.c:10\nmsgid "Source"\nmsgstr "Target"\n\n'''
+ poexpected1 = '''#: location.c:1\n#, fuzzy\nmsgid ""\n"_: location.c:1\\n"\n"Source"\nmsgstr "Target"\n'''
+ poexpected2 = '''#: location.c:10\n#, fuzzy\nmsgid ""\n"_: location.c:10\\n"\n"Source"\nmsgstr "Target"\n'''
+ newpo = self.convertpot(potsource, posource)
+ print "Expected:\n", poexpected1, "Actual:\n", newpo.units[1]
+ assert str(newpo.units[1]) == poexpected1
+ assert str(newpo.units[2]) == poexpected2
+
+ def wtest_merging_accelerator_changes(self):
+ """test that a change in the accelerator localtion still allows merging"""
+ potsource = '''#: someline.c\nmsgid "A&bout"\nmsgstr ""\n'''
+ posource = '''#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n'''
+ poexpected = '''#: someline.c\nmsgid "A&bout"\nmsgstr "&Info"\n'''
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ assert str(self.singleunit(newpo)) == poexpected
+
+ def xtest_lines_cut_differently(self):
+ """Checks that the correct formatting is preserved when pot an po lines differ."""
+ potsource = '''#: simple.label\nmsgid "Line split "\n"differently"\nmsgstr ""\n'''
+ posource = '''#: simple.label\nmsgid "Line"\n" split differently"\nmsgstr "Lyne verskillend gesny"\n'''
+ newpo = self.convertpot(potsource, posource)
+ newpounit = self.singleunit(newpo)
+ assert str(newpounit) == posource
+
+ def test_merging_automatic_comments_dont_duplicate(self):
+ """ensure that we can merge #. comments correctly"""
+ potsource = '''#. Row 35\nmsgid "&About"\nmsgstr ""\n'''
+ posource = '''#. Row 35\nmsgid "&About"\nmsgstr "&Info"\n'''
+ newpo = self.convertpot(potsource, posource)
+ newpounit = self.singleunit(newpo)
+ assert str(newpounit) == posource
+
+ def test_merging_automatic_comments_new_overides_old(self):
+ """ensure that new #. comments override the old comments"""
+ potsource = '''#. new comment\n#: someline.c\nmsgid "&About"\nmsgstr ""\n'''
+ posource = '''#. old comment\n#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n'''
+ poexpected = '''#. new comment\n#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n'''
+ newpo = self.convertpot(potsource, posource)
+ newpounit = self.singleunit(newpo)
+ assert str(newpounit) == poexpected
+
+ def test_merging_comments_with_blank_comment_lines(self):
+ """test that when we merge a comment that has a blank line we keep the blank line"""
+ potsource = '''#: someline.c\nmsgid "About"\nmsgstr ""\n'''
+ posource = '''# comment1\n#\n# comment2\n#: someline.c\nmsgid "About"\nmsgstr "Omtrent"\n'''
+ poexpected = posource
+ newpo = self.convertpot(potsource, posource)
+ newpounit = self.singleunit(newpo)
+ assert str(newpounit) == poexpected
+
+ def test_empty_commentlines(self):
+ potsource = '''#: paneSecurity.title
+msgid "Security"
+msgstr ""
+'''
+ posource = '''# - Contributor(s):
+# -
+# - Alternatively, the
+# -
+#: paneSecurity.title
+msgid "Security"
+msgstr "Sekuriteit"
+'''
+ poexpected = posource
+ newpo = self.convertpot(potsource, posource)
+ newpounit = self.singleunit(newpo)
+ print "expected"
+ print poexpected
+ print "got:"
+ print str(newpounit)
+ assert str(newpounit) == poexpected
+
+ def test_merging_msgidcomments(self):
+ """ensure that we can merge msgidcomments messages"""
+ potsource = r'''#: window.width
+msgid ""
+"_: Do not translate this.\n"
+"36em"
+msgstr ""
+'''
+ posource = r'''#: window.width
+msgid ""
+"_: Do not translate this.\n"
+"36em"
+msgstr "36em"
+'''
+ newpo = self.convertpot(potsource, posource)
+ newpounit = self.singleunit(newpo)
+ assert str(newpounit) == posource
+
+ def test_merging_msgid_with_msgidcomment(self):
+ """test that we can merge an otherwise identical string that has a different msgid"""
+ potsource = r'''#: pref.certs.title
+msgid ""
+"_: pref.certs.title\n"
+"Certificates"
+msgstr ""
+
+#: certs.label
+msgid ""
+"_: certs.label\n"
+"Certificates"
+msgstr ""
+'''
+ posource = r'''#: pref.certs.title
+msgid ""
+"_: pref.certs.title\n"
+"Certificates"
+msgstr ""
+
+#: certs.label
+msgid ""
+"_: certs.label\n"
+"Certificates"
+msgstr "Sertifikate"
+'''
+ expected = r'''#: pref.certs.title
+#, fuzzy
+msgid ""
+"_: pref.certs.title\n"
+"Certificates"
+msgstr "Sertifikate"
+'''
+ newpo = self.convertpot(potsource, posource)
+ newpounit = newpo.units[1]
+ assert str(newpounit) == expected
+
+ def test_merging_plurals(self):
+ """ensure that we can merge plural messages"""
+ potsource = '''msgid "One"\nmsgid_plural "Two"\nmsgstr[0] ""\nmsgstr[1] ""\n'''
+ posource = '''msgid "One"\nmsgid_plural "Two"\nmsgstr[0] "Een"\nmsgstr[1] "Twee"\nmsgstr[2] "Drie"\n'''
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ newpounit = self.singleunit(newpo)
+ assert str(newpounit) == posource
+
+ def test_merging_obsoleting_messages(self):
+ """check that we obsolete messages no longer present in the new file"""
+ #add emtpy msgid line to help factory identify format
+ potsource = 'msgid ""\nmsgstr ""\n'
+ posource = '# Some comment\n#. Extracted comment\n#: obsoleteme:10\nmsgid "One"\nmsgstr "Een"\n'
+ expected = '# Some comment\n#~ msgid "One"\n#~ msgstr "Een"\n'
+ newpo = self.convertpot(potsource, posource)
+ print str(newpo)
+ newpounit = self.singleunit(newpo)
+ assert str(newpounit) == expected
+
+ def test_not_obsoleting_empty_messages(self):
+ """check that we don't obsolete (and keep) untranslated messages"""
+ #add emtpy msgid line to help factory identify format
+ potsource = 'msgid ""\nmsgstr ""\n'
+ posource = '#: obsoleteme:10\nmsgid "One"\nmsgstr ""\n'
+ newpo = self.convertpot(potsource, posource)
+ print str(newpo)
+ # We should only have the header
+ assert len(newpo.units) == 1
+
+ def test_merging_new_before_obsolete(self):
+ """test to check that we place new blank message before obsolete messages"""
+ potsource = '''#: newline.c\nmsgid "&About"\nmsgstr ""\n'''
+ posource = '''#~ msgid "Old"\n#~ msgstr "Oud"\n'''
+ newpo = self.convertpot(potsource, posource)
+ assert len(newpo.units) == 3
+ assert newpo.units[0].isheader()
+ assert newpo.units[2].isobsolete()
+ assert str(newpo.units[1]) == potsource
+ assert str(newpo.units[2]) == posource
+
+ # Now test with real units present in posource
+ posource2 = '''msgid "Old"\nmsgstr "Oud"\n'''
+ newpo = self.convertpot(potsource, posource)
+ assert len(newpo.units) == 3
+ assert newpo.units[0].isheader()
+ assert newpo.units[2].isobsolete()
+ assert str(newpo.units[1]) == potsource
+ assert str(newpo.units[2]) == posource
+
+ def test_merging_resurect_obsolete_messages(self):
+ """check that we can reuse old obsolete messages if the message comes back"""
+ potsource = '''#: resurect.c\nmsgid "&About"\nmsgstr ""\n'''
+ posource = '''#~ msgid "&About"\n#~ msgstr "&Omtrent"\n'''
+ expected = '''#: resurect.c\nmsgid "&About"\nmsgstr "&Omtrent"\n'''
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ assert len(newpo.units) == 2
+ assert newpo.units[0].isheader()
+ newpounit = self.singleunit(newpo)
+ assert str(newpounit) == expected
+
+ def test_merging_resurect_obsolete_messages_into_msgidcomment(self):
+ """check that we can reuse old obsolete messages even if the recipient has a msgidcomment"""
+ potsource = '''#: resurect1.c\nmsgid "About"\nmsgstr ""\n\n''' + \
+ '''#: resurect2.c\nmsgid ""\n"_: resurect2.c\\n"\n"About"\nmsgstr ""\n'''
+ posource = '''#~ msgid "About"\n#~ msgstr "Omtrent"\n'''
+ expected1 = '''#: resurect1.c\nmsgid "About"\nmsgstr "Omtrent"\n'''
+ expected2 = '''#: resurect2.c\n#, fuzzy\nmsgid ""\n"_: resurect2.c\\n"\n"About"\nmsgstr "Omtrent"\n'''
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ assert len(newpo.units) == 3
+ assert newpo.units[0].isheader()
+ assert str(newpo.units[1]) == expected1
+ assert str(newpo.units[2]) == expected2
+
+ def test_header_initialisation(self):
+ """test to check that we initialise the header correctly"""
+ potsource = r'''#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: new@example.com\n"
+"POT-Creation-Date: 2006-11-11 11:11+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+"X-Generator: Translate Toolkit 0.10rc2\n"
+'''
+ posource = r'''msgid ""
+msgstr ""
+"Project-Id-Version: Pootle 0.10\n"
+"Report-Msgid-Bugs-To: old@example.com\n"
+"POT-Creation-Date: 2006-01-01 01:01+0100\n"
+"PO-Revision-Date: 2006-09-09 09:09+0900\n"
+"Last-Translator: Joe Translate <joe@example.com>\n"
+"Language-Team: Pig Latin <piglatin@example.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Translate Toolkit 0.9\n"
+'''
+ expected = r'''msgid ""
+msgstr ""
+"Project-Id-Version: Pootle 0.10\n"
+"Report-Msgid-Bugs-To: new@example.com\n"
+"POT-Creation-Date: 2006-11-11 11:11+0000\n"
+"PO-Revision-Date: 2006-09-09 09:09+0900\n"
+"Last-Translator: Joe Translate <joe@example.com>\n"
+"Language-Team: Pig Latin <piglatin@example.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Translate Toolkit 0.10rc2\n"
+'''
+ newpo = self.convertpot(potsource, posource)
+ print 'Output Header:\n%s' % newpo
+ print 'Expected Header:\n%s' % expected
+ assert str(newpo) == expected
+
+ def test_merging_comments(self):
+ """Test that we can merge comments correctly"""
+ potsource = '''#. Don't do it!\n#: file.py:1\nmsgid "One"\nmsgstr ""\n'''
+ posource = '''#. Don't do it!\n#: file.py:2\nmsgid "One"\nmsgstr "Een"\n'''
+ poexpected = '''#. Don't do it!\n#: file.py:1\nmsgid "One"\nmsgstr "Een"\n'''
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ newpounit = self.singleunit(newpo)
+ assert str(newpounit) == poexpected
+
+ def test_merging_typecomments(self):
+ """Test that we can merge with typecomments"""
+ potsource = '''#: file.c:1\n#, c-format\nmsgid "%d pipes"\nmsgstr ""\n'''
+ posource = '''#: file.c:2\nmsgid "%d pipes"\nmsgstr "%d pype"\n'''
+ poexpected = '''#: file.c:1\n#, c-format\nmsgid "%d pipes"\nmsgstr "%d pype"\n'''
+ newpo = self.convertpot(potsource, posource)
+ newpounit = self.singleunit(newpo)
+ print newpounit
+ assert str(newpounit) == poexpected
+
+ potsource = '''#: file.c:1\n#, c-format\nmsgid "%d computers"\nmsgstr ""\n'''
+ posource = '''#: file.c:2\n#, c-format\nmsgid "%s computers "\nmsgstr "%s-rekenaars"\n'''
+ poexpected = '''#: file.c:1\n#, fuzzy, c-format\nmsgid "%d computers"\nmsgstr "%s-rekenaars"\n'''
+ newpo = self.convertpot(potsource, posource)
+ newpounit = self.singleunit(newpo)
+ assert newpounit.isfuzzy()
+ assert newpounit.hastypecomment("c-format")
+
+ def test_msgctxt(self):
+ """Test that msgctxt is migrated correctly"""
+ potsource = """
+#: something.h:5
+msgctxt "context1"
+msgid "text"
+msgstr ""
+
+#: something.h:6
+msgctxt "context2"
+msgid "text"
+msgstr ""
+"""
+ posource = """
+#: something.h:3
+msgctxt "context0"
+msgid "text"
+msgstr "teks"
+
+#: something.h:4
+msgctxt "context1"
+msgid "text"
+msgstr "sms"
+"""
+ poexpected = """
+#: something.h:5
+msgctxt "context1"
+msgid "text"
+msgstr "sms"
+
+#: something.h:6
+#, fuzzy
+msgctxt "context2"
+msgid "text"
+msgstr "teks"
+"""
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ assert poexpected in str(newpo)
+
+ def test_empty_msgid(self):
+ """Test that we handle empty msgids correctly."""
+ #TODO: this test will fail if we don't have the gettext location
+ # comment in the pot file
+ potsource = '#: file:1\nmsgctxt "bla"\nmsgid ""\nmsgstr ""\n'
+ posource = r"""
+msgid ""
+"Project-Id-Version: Pootle 0.10\n"
+msgstr ""
+
+msgctxt "bla"
+msgid ""
+msgstr "trans"
+"""
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ assert len(newpo.units) == 2
+ assert newpo.units[0].isheader()
+ unit = newpo.units[1]
+ assert unit.source == u""
+ assert unit.getid() == u"bla\04"
+ assert unit.target == "trans"
+ assert not unit.isfuzzy()
+
+ def test_migrate_msgidcomment_to_msgctxt(self):
+ """Test that we migrate correctly from msgidcomments to msgctxt.
+
+ This is needed for our move away from using msgidcomments for mozilla."""
+ potsource = '#: bla\nmsgctxt "bla"\nmsgid ""\nmsgstr ""'
+ posource = r"""
+msgid ""
+"Project-Id-Version: Pootle 0.10\n"
+msgstr ""
+
+#: bla
+msgid ""
+"_: bla\n"
+msgstr "trans"
+"""
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ assert len(newpo.units) == 2
+ assert newpo.units[0].isheader()
+ unit = newpo.units[1]
+ assert unit.source == u""
+ assert unit.getid() == u"bla\04"
+ assert unit.target == "trans"
+ assert not unit.isfuzzy()
+
+ def test_obsolete_msgctxt(self):
+ """Test that obsolete units' msgctxt is preserved."""
+ potsource = 'msgctxt "newContext"\nmsgid "First unit"\nmsgstr ""'
+ posource = """
+msgctxt "newContext"
+msgid "First unit"
+msgstr "Eerste eenheid"
+
+#~ msgctxt "context"
+#~ msgid "Old unit"
+#~ msgstr "Ou eenheid1"
+
+#~ msgctxt "context2"
+#~ msgid "Old unit"
+#~ msgstr "Ou eenheid2"
+
+#~ msgid "Old unit"
+#~ msgstr "Ou eenheid3"
+"""
+ newpo = self.convertpot(potsource, posource)
+ print newpo
+ assert len(newpo.units) == 5
+ assert newpo.units[1].getcontext() == 'newContext'
+ # Search in unit string, because obsolete units can't return a context
+ assert 'msgctxt "context"' in str(newpo.units[2])
+ assert 'msgctxt "context2"' in str(newpo.units[3])
+
+ def test_small_strings(self):
+ """Test that units with small source strings are not incorrectly
+ populated by means of fuzzy matching."""
+ potsource = r'''#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: new@example.com\n"
+"POT-Creation-Date: 2006-11-11 11:11+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+"X-Generator: Translate Toolkit 0.10rc2\n"
+
+#: new_disassociated_mozilla_accesskey
+msgid "R"
+msgstr ""
+'''
+ posource = r'''msgid ""
+msgstr ""
+"Project-Id-Version: Pootle 0.10\n"
+"Report-Msgid-Bugs-To: old@example.com\n"
+"POT-Creation-Date: 2006-01-01 01:01+0100\n"
+"PO-Revision-Date: 2006-09-09 09:09+0900\n"
+"Last-Translator: Joe Translate <joe@example.com>\n"
+"Language-Team: Pig Latin <piglatin@example.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Translate Toolkit 0.9\n"
+
+#: old_disassociated_mozilla_accesskey
+msgid "R"
+msgstr "S"
+'''
+ expected = r'''msgid ""
+msgstr ""
+"Project-Id-Version: Pootle 0.10\n"
+"Report-Msgid-Bugs-To: new@example.com\n"
+"POT-Creation-Date: 2006-11-11 11:11+0000\n"
+"PO-Revision-Date: 2006-09-09 09:09+0900\n"
+"Last-Translator: Joe Translate <joe@example.com>\n"
+"Language-Team: Pig Latin <piglatin@example.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Translate Toolkit 0.10rc2\n"
+
+#: new_disassociated_mozilla_accesskey
+msgid "R"
+msgstr ""
+'''
+ newpo = self.convertpot(potsource, posource)
+ print 'Output:\n%s' % newpo
+ print 'Expected:\n%s' % expected
+ assert str(newpo) == expected
+
+
+class TestPOT2POCommand(test_convert.TestConvertCommand, TestPOT2PO):
+ """Tests running actual pot2po commands on files"""
+ convertmodule = pot2po
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "-P, --pot")
+ options = self.help_check(options, "--tm")
+ options = self.help_check(options, "-s MIN_SIMILARITY, --similarity=MIN_SIMILARITY")
+ options = self.help_check(options, "--nofuzzymatching", last=True)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_prop2mozfunny.py b/translate-toolkit-1.5.1/translate/convert/test_prop2mozfunny.py
new file mode 100644
index 0000000..e5deb52
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_prop2mozfunny.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+
+from translate.convert import prop2mozfunny
+from translate.misc import wStringIO
+
+class TestPO2Prop:
+ def merge2inc(self, incsource, posource):
+ """helper that merges po translations to .inc source without requiring files"""
+ inputfile = wStringIO.StringIO(posource)
+ templatefile = wStringIO.StringIO(incsource)
+ outputfile = wStringIO.StringIO()
+ result = prop2mozfunny.po2inc(inputfile, outputfile, templatefile)
+ outputinc = outputfile.getvalue()
+ print outputinc
+ assert result
+ return outputinc
+
+ def test_no_endlines_added(self):
+ """check that we don't add newlines at the end of file"""
+ posource = '''# converted from #defines file\n#: MOZ_LANG_TITLE\nmsgid "English (US)"\nmsgstr "Deutsch (DE)"\n\n'''
+ inctemplate = '''#define MOZ_LANG_TITLE Deutsch (DE)\n'''
+ incexpected = inctemplate
+ incfile = self.merge2inc(inctemplate, posource)
+ print incfile
+ assert incfile == incexpected
+
+ def test_uncomment_contributors(self):
+ """check that we handle uncommenting contributors properly"""
+ posource = '''# converted from #defines file
+#: MOZ_LANGPACK_CONTRIBUTORS
+msgid "<em:contributor>Joe Solon</em:contributor>"
+msgstr "<em:contributor>Mr Fury</em:contributor>"
+'''
+ inctemplate = '''# #define MOZ_LANGPACK_CONTRIBUTORS <em:contributor>Joe Solon</em:contributor>\n'''
+ incexpected = '''#define MOZ_LANGPACK_CONTRIBUTORS <em:contributor>Mr Fury</em:contributor>\n'''
+ incfile = self.merge2inc(inctemplate, posource)
+ print incfile
+ assert incfile == incexpected
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_prop2po.py b/translate-toolkit-1.5.1/translate/convert/test_prop2po.py
new file mode 100644
index 0000000..0a8bb17
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_prop2po.py
@@ -0,0 +1,210 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import prop2po
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import po
+from translate.storage import properties
+
+class TestProp2PO:
+ def prop2po(self, propsource, proptemplate=None):
+ """helper that converts .properties source to po source without requiring files"""
+ inputfile = wStringIO.StringIO(propsource)
+ inputprop = properties.propfile(inputfile)
+ convertor = prop2po.prop2po()
+ if proptemplate:
+ templatefile = wStringIO.StringIO(proptemplate)
+ templateprop = properties.propfile(templatefile)
+ outputpo = convertor.mergestore(templateprop, inputprop)
+ else:
+ outputpo = convertor.convertstore(inputprop)
+ return outputpo
+
+ def convertprop(self, propsource):
+ """call the convertprop, return the outputfile"""
+ inputfile = wStringIO.StringIO(propsource)
+ outputfile = wStringIO.StringIO()
+ templatefile = None
+ assert prop2po.convertprop(inputfile, outputfile, templatefile)
+ return outputfile.getvalue()
+
+ def singleelement(self, pofile):
+ """checks that the pofile contains a single non-header element, and returns it"""
+ assert len(pofile.units) == 2
+ assert pofile.units[0].isheader()
+ print pofile
+ return pofile.units[1]
+
+ def countelements(self, pofile):
+ """counts the number of non-header entries"""
+ assert pofile.units[0].isheader()
+ print pofile
+ return len(pofile.units) - 1
+
+ def test_simpleentry(self):
+ """checks that a simple properties entry converts properly to a po entry"""
+ propsource = 'SAVEENTRY=Save file\n'
+ pofile = self.prop2po(propsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "Save file"
+ assert pounit.target == ""
+
+ def test_convertprop(self):
+ """checks that the convertprop function is working"""
+ propsource = 'SAVEENTRY=Save file\n'
+ posource = self.convertprop(propsource)
+ pofile = po.pofile(wStringIO.StringIO(posource))
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "Save file"
+ assert pounit.target == ""
+
+ def test_tab_at_end_of_string(self):
+ """check that we preserve tabs at the end of a string"""
+ propsource = r"TAB_AT_END=This setence has a tab at the end.\t"
+ pofile = self.prop2po(propsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "This setence has a tab at the end.\t"
+
+ propsource = r"SPACE_THEN_TAB_AT_END=This setence has a space then tab at the end. \t"
+ pofile = self.prop2po(propsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "This setence has a space then tab at the end. \t"
+
+ propsource = r"SPACE_AT_END=This setence will keep its 4 spaces at the end. "
+ pofile = self.prop2po(propsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "This setence will keep its 4 spaces at the end. "
+
+ propsource = r"SPACE_AT_END_NO_TRIM=This setence will keep its 4 spaces at the end.\\ "
+ pofile = self.prop2po(propsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.source == "This setence will keep its 4 spaces at the end. "
+
+ def test_tab_at_start_of_value(self):
+ """check that tabs in a property are ignored where appropriate"""
+ propsource = r"property = value"
+ pofile = self.prop2po(propsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.getlocations()[0] == "property"
+ assert pounit.source == "value"
+
+ def test_unicode(self):
+ """checks that unicode entries convert properly"""
+ unistring = r'Norsk bokm\u00E5l'
+ propsource = 'nb = %s\n' % unistring
+ pofile = self.prop2po(propsource)
+ pounit = self.singleelement(pofile)
+ print repr(pofile.units[0].target)
+ print repr(pounit.source)
+ assert pounit.source == u'Norsk bokm\u00E5l'
+
+ def test_multiline_escaping(self):
+ """checks that multiline enties can be parsed"""
+ propsource = r"""5093=Unable to connect to your IMAP server. You may have exceeded the maximum number \
+of connections to this server. If so, use the Advanced IMAP Server Settings dialog to \
+reduce the number of cached connections."""
+ pofile = self.prop2po(propsource)
+ print repr(pofile.units[1].target)
+ assert self.countelements(pofile) == 1
+
+ def test_comments(self):
+ """test to ensure that we take comments from .properties and place them in .po"""
+ propsource = '''# Comment
+prefPanel-smime=Security'''
+ pofile = self.prop2po(propsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.getnotes("developer") == "# Comment"
+
+ def test_multiline_comments(self):
+ """test to ensure that we handle multiline comments well"""
+ propsource = '''# Comment
+# commenty 2
+
+## @name GENERIC_ERROR
+## @loc none
+prefPanel-smime=
+'''
+ pofile = self.prop2po(propsource)
+ print str(pofile)
+ #header comments:
+ assert "#. # Comment\n#. # commenty 2" in str(pofile)
+ pounit = self.singleelement(pofile)
+ assert pounit.getnotes("developer") == "## @name GENERIC_ERROR\n## @loc none"
+
+ def wtest_folding_accesskeys(self):
+ """check that we can fold various accesskeys into their associated label (bug #115)"""
+ propsource = r'''cmd_addEngine = Add Engines...
+cmd_addEngine_accesskey = A'''
+ pofile = self.prop2po(propsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.target == "&Add Engines..."
+
+ def test_dont_translate(self):
+ """check that we know how to ignore don't translate instructions in properties files (bug #116)"""
+ propsource = '''# LOCALIZATION NOTE (dont): DONT_TRANSLATE.
+dont=don't translate me
+do=translate me
+'''
+ pofile = self.prop2po(propsource)
+ assert self.countelements(pofile) == 1
+
+ def test_emptyproperty(self):
+ """checks that empty property definitions survive into po file, bug 15"""
+ propsource = '# comment\ncredit='
+ pofile = self.prop2po(propsource)
+ pounit = self.singleelement(pofile)
+ assert pounit.getlocations() == ["credit"]
+ assert pounit.getcontext() == "credit"
+ assert 'msgctxt "credit"' in str(pounit)
+ assert "#. # comment" in str(pofile)
+ assert pounit.source == ""
+
+ def test_emptyproperty_translated(self):
+ """checks that if we translate an empty property it makes it into the PO"""
+ proptemplate = 'credit='
+ propsource = 'credit=Translators Names'
+ pofile = self.prop2po(propsource, proptemplate)
+ pounit = self.singleelement(pofile)
+ assert pounit.getlocations() == ["credit"]
+ # FIXME we don't seem to get a _: comment but we should
+ #assert pounit.getcontext() == "credit"
+ assert pounit.source == ""
+ assert pounit.target == "Translators Names"
+
+ def test_newlines_in_value(self):
+ """check that we can carry newlines that appear in the property value into the PO"""
+ propsource = '''prop=\\nvalue\\n\n'''
+ pofile = self.prop2po(propsource)
+ unit = self.singleelement(pofile)
+ assert unit.source == "\nvalue\n"
+
+ def test_unassociated_comments(self):
+ """check that we can handle comments not directly associated with a property"""
+ propsource = '''# Header comment\n\n# Comment\n\nprop=value\n'''
+ pofile = self.prop2po(propsource)
+ unit = self.singleelement(pofile)
+ assert unit.source == "value"
+ assert unit.getnotes("developer") == "# Comment"
+
+ def test_unassociated_comment_order(self):
+ """check that we can handle the order of unassociated comments"""
+ propsource = '''# Header comment\n\n# 1st Unassociated comment\n\n# 2nd Connected comment\nprop=value\n'''
+ pofile = self.prop2po(propsource)
+ unit = self.singleelement(pofile)
+ assert unit.source == "value"
+ assert unit.getnotes("developer") == "# 1st Unassociated comment\n# 2nd Connected comment"
+
+class TestProp2POCommand(test_convert.TestConvertCommand, TestProp2PO):
+ """Tests running actual prop2po commands on files"""
+ convertmodule = prop2po
+ defaultoptions = {"progress": "none"}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-P, --pot")
+ options = self.help_check(options, "-t TEMPLATE, --template=TEMPLATE")
+ options = self.help_check(options, "--personality=TYPE")
+ options = self.help_check(options, "--duplicates=DUPLICATESTYLE", last=True)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/test_tiki2po.py b/translate-toolkit-1.5.1/translate/convert/test_tiki2po.py
new file mode 100644
index 0000000..8024b41
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_tiki2po.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# tiki2po unit tests
+# Author: Wil Clouser <wclouser@mozilla.com>
+# Date: 2008-12-01
+
+from translate.convert import tiki2po
+from translate.storage import tiki
+from translate.convert import test_convert
+from translate.misc import wStringIO
+
+class TestTiki2Po:
+ def test_converttiki_defaults(self):
+ inputfile = """
+"zero_source" => "zero_target",
+// ### Start of unused words
+"one_source" => "one_target",
+// ### end of unused words
+ """
+ outputfile = wStringIO.StringIO()
+ tiki2po.converttiki(inputfile, outputfile)
+
+ output = outputfile.getvalue()
+
+ assert '#: translated' in output
+ assert 'msgid "zero_source"' in output
+ assert "one_source" not in output
+
+ def test_converttiki_includeunused(self):
+ inputfile = """
+"zero_source" => "zero_target",
+// ### Start of unused words
+"one_source" => "one_target",
+// ### end of unused words
+ """
+ outputfile = wStringIO.StringIO()
+ tiki2po.converttiki(inputfile, outputfile, includeunused=True)
+
+ output = outputfile.getvalue()
+
+ assert '#: translated' in output
+ assert 'msgid "zero_source"' in output
+ assert '#: unused' in output
+ assert 'msgid "one_source"' in output
+
+
+class TestTiki2PoCommand(test_convert.TestConvertCommand, TestTiki2Po):
+ """Tests running actual tiki2po commands on files"""
+ convertmodule = tiki2po
+ defaultoptions = {}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "--include-unused")
diff --git a/translate-toolkit-1.5.1/translate/convert/test_ts2po.py b/translate-toolkit-1.5.1/translate/convert/test_ts2po.py
new file mode 100644
index 0000000..c5a11dd
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_ts2po.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from translate.convert import ts2po
+from translate.convert import test_convert
+from translate.misc import wStringIO
+
+class TestTS2PO:
+ def ts2po(self, tssource):
+ converter = ts2po.ts2po()
+ tsfile = wStringIO.StringIO(tssource)
+ outputpo = converter.convertfile(tsfile)
+ print "The generated po:"
+ print str(outputpo)
+ return outputpo
+
+ def test_blank(self):
+ """tests blank conversion"""
+ tssource = '''<!DOCTYPE TS><TS>
+<context>
+ <name>MainWindowBase</name>
+ <message>
+ <source>Project:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
+'''
+ pofile = self.ts2po(tssource)
+ assert len(pofile.units) == 2
+ assert pofile.units[1].source == "Project:"
+ assert pofile.units[1].target == ""
+ assert pofile.units[1].getlocations()[0].startswith("MainWindowBase")
+ assert not pofile.units[1].isfuzzy()
+
+ def test_basic(self):
+ """tests basic conversion"""
+ tssource = '''<!DOCTYPE TS><TS>
+<context>
+ <name>AboutDialog</name>
+ <message>
+ <source>&amp;About</source>
+ <translation>&amp;Giới thiệu</translation>
+ </message>
+</context>
+</TS>
+'''
+ pofile = self.ts2po(tssource)
+ assert len(pofile.units) == 2
+ assert pofile.units[1].source == "&About"
+ assert pofile.units[1].target == u"&Giới thiệu"
+ assert pofile.units[1].getlocations()[0].startswith("AboutDialog")
+
+ def test_unfinished(self):
+ """tests unfinished conversion"""
+ tssource = '''<!DOCTYPE TS><TS>
+<context>
+ <name>MainWindowBase</name>
+ <message>
+ <source>Project:</source>
+ <translation type="unfinished">Projek vergardering</translation>
+ </message>
+</context>
+</TS>
+'''
+ pofile = self.ts2po(tssource)
+ assert len(pofile.units) == 2
+ assert pofile.units[1].source == "Project:"
+ assert pofile.units[1].target == "Projek vergardering"
+ assert pofile.units[1].getlocations()[0].startswith("MainWindowBase")
+ assert pofile.units[1].isfuzzy()
+
+ def test_multiline(self):
+ """tests multiline message conversion"""
+ tssource = '''<!DOCTYPE TS><TS>
+<context>
+ <name>@default</name>
+ <message>
+ <source>Source with
+new line</source>
+ <translation>Test with
+new line</translation>
+ </message>
+</context>
+</TS>
+'''
+ pofile = self.ts2po(tssource)
+ assert len(pofile.units) == 2
+ assert pofile.units[1].source == "Source with\nnew line"
+ assert pofile.units[1].target == "Test with\nnew line"
+ assert pofile.units[1].getlocations()[0].startswith("@default")
+
+ def test_obsolete(self):
+ """test the handling of obsolete TS entries"""
+ tssource = '''<!DOCTYPE TS><TS>
+<context>
+ <name>Obsoleted</name>
+ <message>
+ <source>Failed</source>
+ <translation type="obsolete">Mislukt</translation>
+ </message>
+</context>
+</TS>
+'''
+ pofile = self.ts2po(tssource)
+ assert pofile.units[1].getnotes("developer") == "(obsolete)"
+ # Test that we aren't following the old style
+ assert "_ OBSOLETE" not in pofile.units[1].getnotes()
+
+class TestTS2POCommand(test_convert.TestConvertCommand, TestTS2PO):
+ """Tests running actual ts2po commands on files"""
+ convertmodule = ts2po
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "--duplicates=DUPLICATESTYLE")
+ options = self.help_check(options, "-P, --pot", last=True)
diff --git a/translate-toolkit-1.5.1/translate/convert/test_txt2po.py b/translate-toolkit-1.5.1/translate/convert/test_txt2po.py
new file mode 100644
index 0000000..5f8bb82
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_txt2po.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+
+from translate.convert import txt2po
+from translate.convert import test_convert
+from translate.misc import wStringIO
+from translate.storage import txt
+
+class TestTxt2PO:
+ def txt2po(self, txtsource, template=None):
+ """helper that converts txt source to po source without requiring files"""
+ inputfile = wStringIO.StringIO(txtsource)
+ inputtxt = txt.TxtFile(inputfile)
+ convertor = txt2po.txt2po()
+ outputpo = convertor.convertstore(inputtxt)
+ return outputpo
+
+ def singleelement(self, storage):
+ """checks that the pofile contains a single non-header element, and returns it"""
+ print str(storage)
+ assert len(storage.units) == 1
+ return storage.units[0]
+
+ def test_simple(self):
+ """test the most basic txt conversion"""
+ txtsource = "A simple string"
+ poexpected = '''#: :1
+msgid "A simple string"
+msgstr ""
+'''
+ poresult = self.txt2po(txtsource)
+ assert str(poresult.units[1]) == poexpected
+
+ def test_miltiple_units(self):
+ """test that we can handle txt with multiple units"""
+ txtsource = """First unit
+Still part of first unit
+
+Second unit is a heading
+------------------------
+
+Third unit with blank after but no more units.
+
+"""
+ poresult = self.txt2po(txtsource)
+ assert poresult.units[0].isheader()
+ assert len(poresult.units) == 4
+
+ def test_carriage_return(self):
+ """Remove carriage returns from files in dos format."""
+ txtsource = '''The rapid expansion of telecommunications infrastructure in recent years has\r
+helped to bridge the digital divide to a limited extent.\r
+'''
+
+ txtexpected = '''The rapid expansion of telecommunications infrastructure in recent years has
+helped to bridge the digital divide to a limited extent.'''
+
+ poresult = self.txt2po(txtsource)
+ pounit = poresult.units[1]
+ assert str(pounit.getsource()) == txtexpected
+
+class TestDoku2po:
+ def doku2po(self, txtsource, template=None):
+ """helper that converts dokuwiki source to po source without requiring files."""
+ inputfile = wStringIO.StringIO(txtsource)
+ inputtxt = txt.TxtFile(inputfile, flavour="dokuwiki")
+ convertor = txt2po.txt2po()
+ outputpo = convertor.convertstore(inputtxt)
+ return outputpo
+
+ def singleelement(self, storage):
+ """checks that the pofile contains a single non-header element, and returns it"""
+ print str(storage)
+ assert len(storage.units) == 1
+ return storage.units[0]
+
+ def test_basic(self):
+ """Tests that we can convert some basic things."""
+ dokusource = """=====Heading=====
+
+This is a wiki page.
+"""
+ poresult = self.doku2po(dokusource)
+ assert poresult.units[0].isheader()
+ assert len(poresult.units) == 3
+ assert poresult.units[1].source == "Heading"
+ assert poresult.units[2].source == "This is a wiki page."
+
+ def test_bullets(self):
+ """Tests that we can convert some basic things."""
+ dokusource = """ * This is a fact.
+ * This is a fact.
+"""
+ poresult = self.doku2po(dokusource)
+ assert poresult.units[0].isheader()
+ assert len(poresult.units) == 3
+ assert poresult.units[1].source == "This is a fact."
+ assert poresult.units[2].source == "This is a fact."
+
+ def test_numbers(self):
+ """Tests that we can convert some basic things."""
+ dokusource = """ - This is an item.
+ - This is an item.
+"""
+ poresult = self.doku2po(dokusource)
+ assert poresult.units[0].isheader()
+ assert len(poresult.units) == 3
+ assert poresult.units[1].source == "This is an item."
+ assert poresult.units[2].source == "This is an item."
+
+ def test_spacing(self):
+ """Tests that we can convert some basic things."""
+ dokusource = """ ===== Heading =====
+ * This is an item.
+ * This is a subitem.
+ * This is a tabbed item.
+"""
+ poresult = self.doku2po(dokusource)
+ assert poresult.units[0].isheader()
+ assert len(poresult.units) == 5
+ assert poresult.units[1].source == "Heading"
+ assert poresult.units[2].source == "This is an item."
+ assert poresult.units[3].source == "This is a subitem."
+ assert poresult.units[4].source == "This is a tabbed item."
+
+class TestTxt2POCommand(test_convert.TestConvertCommand, TestTxt2PO):
+ """Tests running actual txt2po commands on files"""
+ convertmodule = txt2po
+ defaultoptions = {"progress": "none"}
+
+ def test_help(self):
+ """tests getting help"""
+ options = test_convert.TestConvertCommand.test_help(self)
+ options = self.help_check(options, "-P, --pot")
+ options = self.help_check(options, "--duplicates")
+ options = self.help_check(options, "--encoding")
+ options = self.help_check(options, "--flavour", last=True)
diff --git a/translate-toolkit-1.5.1/translate/convert/test_xliff2po.py b/translate-toolkit-1.5.1/translate/convert/test_xliff2po.py
new file mode 100644
index 0000000..7de6c74
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/test_xliff2po.py
@@ -0,0 +1,220 @@
+#!/usr/bin/env python
+
+from translate.convert import xliff2po
+from translate.misc import wStringIO
+
+class TestXLIFF2PO:
+ xliffskeleton = '''<?xml version="1.0" ?>
+<xliff version="1.1" xmlns="urn:oasis:names:tc:xliff:document:1.1">
+ <file original="filename.po" source-language="en-US" datatype="po">
+ <body>
+ %s
+ </body>
+ </file>
+</xliff>'''
+
+ def xliff2po(self, xliffsource):
+ """helper that converts xliff source to po source without requiring files"""
+ inputfile = wStringIO.StringIO(xliffsource)
+ convertor = xliff2po.xliff2po()
+ outputpo = convertor.convertstore(inputfile)
+ print "The generated po:"
+ print type(outputpo)
+ print str(outputpo)
+ return outputpo
+
+ def test_minimal(self):
+ minixlf = self.xliffskeleton % '''<trans-unit>
+ <source>red</source>
+ <target>rooi</target>
+ </trans-unit>'''
+ pofile = self.xliff2po(minixlf)
+ assert len(pofile.units) == 1
+ assert pofile.translate("red") == "rooi"
+ assert pofile.translate("bla") is None
+
+ def test_basic(self):
+ headertext = '''Project-Id-Version: program 2.1-branch
+Report-Msgid-Bugs-To:
+POT-Creation-Date: 2006-01-09 07:15+0100
+PO-Revision-Date: 2004-03-30 17:02+0200
+Last-Translator: Zuza Software Foundation &lt;xxx@translate.org.za>
+Language-Team: Afrikaans &lt;translate-discuss-xxx@lists.sourceforge.net>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit'''
+
+ minixlf = (self.xliffskeleton % '''<trans-unit id="1" restype="x-gettext-domain-header" approved="no" xml:space="preserve">
+ <source>%s</source>
+ <target>%s</target>
+ <note from="po-translator">Zulu translation of program ABC</note>
+ </trans-unit>
+ <trans-unit>
+ <source>gras</source>
+ <target>utshani</target>
+ </trans-unit>''') % (headertext, headertext)
+
+ print minixlf
+ pofile = self.xliff2po(minixlf)
+ assert pofile.translate("gras") == "utshani"
+ assert pofile.translate("bla") is None
+ potext = str(pofile)
+ assert potext.index('# Zulu translation of program ABC') == 0
+ assert potext.index('msgid "gras"\n')
+ assert potext.index('msgstr "utshani"\n')
+ assert potext.index('MIME-Version: 1.0\\n')
+
+ def test_translatorcomments(self):
+ """Tests translator comments"""
+ minixlf = self.xliffskeleton % '''<trans-unit>
+ <source>nonsense</source>
+ <target>matlhapolosa</target>
+ <context-group name="po-entry" purpose="information">
+ <context context-type="x-po-trancomment">Couldn't do
+it</context>
+ </context-group>
+ <note from="po-translator">Couldn't do
+it</note>
+</trans-unit>'''
+ pofile = self.xliff2po(minixlf)
+ assert pofile.translate("nonsense") == "matlhapolosa"
+ assert pofile.translate("bla") is None
+ unit = pofile.units[0]
+ assert unit.getnotes("translator") == "Couldn't do it"
+ potext = str(pofile)
+ assert potext.index("# Couldn't do it\n") >= 0
+
+ minixlf = self.xliffskeleton % '''<trans-unit xml:space="preserve">
+ <source>nonsense</source>
+ <target>matlhapolosa</target>
+ <context-group name="po-entry" purpose="information">
+ <context context-type="x-po-trancomment">Couldn't do
+it</context>
+ </context-group>
+ <note from="po-translator">Couldn't do
+it</note>
+</trans-unit>'''
+ pofile = self.xliff2po(minixlf)
+ assert pofile.translate("nonsense") == "matlhapolosa"
+ assert pofile.translate("bla") is None
+ unit = pofile.units[0]
+ assert unit.getnotes("translator") == "Couldn't do\nit"
+ potext = str(pofile)
+ assert potext.index("# Couldn't do\n# it\n") >= 0
+
+ def test_autocomment(self):
+ """Tests automatic comments"""
+ minixlf = self.xliffskeleton % '''<trans-unit>
+ <source>nonsense</source>
+ <target>matlhapolosa</target>
+ <context-group name="po-entry" purpose="information">
+ <context context-type="x-po-autocomment">Note that this is
+garbage</context>
+ </context-group>
+ <note from="developer">Note that this is
+garbage</note>
+</trans-unit>'''
+ pofile = self.xliff2po(minixlf)
+ assert pofile.translate("nonsense") == "matlhapolosa"
+ assert pofile.translate("bla") is None
+ unit = pofile.units[0]
+ assert unit.getnotes("developer") == "Note that this is garbage"
+ potext = str(pofile)
+ assert potext.index("#. Note that this is garbage\n") >= 0
+
+ minixlf = self.xliffskeleton % '''<trans-unit xml:space="preserve">
+ <source>nonsense</source>
+ <target>matlhapolosa</target>
+ <context-group name="po-entry" purpose="information">
+ <context context-type="x-po-autocomment">Note that this is
+garbage</context>
+ </context-group>
+ <note from="developer">Note that this is
+garbage</note>
+</trans-unit>'''
+ pofile = self.xliff2po(minixlf)
+ assert pofile.translate("nonsense") == "matlhapolosa"
+ assert pofile.translate("bla") is None
+ unit = pofile.units[0]
+ assert unit.getnotes("developer") == "Note that this is\ngarbage"
+ potext = str(pofile)
+ assert potext.index("#. Note that this is\n#. garbage\n") >= 0
+
+ def test_locations(self):
+ """Tests location comments (#:)"""
+ minixlf = self.xliffskeleton % '''<trans-unit id="1">
+ <source>nonsense</source>
+ <target>matlhapolosa</target>
+ <context-group name="po-reference" purpose="location">
+ <context context-type="sourcefile">example.c</context>
+ <context context-type="linenumber">123</context>
+ </context-group>
+ <context-group name="po-reference" purpose="location">
+ <context context-type="sourcefile">place.py</context>
+ </context-group>
+</trans-unit>'''
+ pofile = self.xliff2po(minixlf)
+ assert pofile.translate("nonsense") == "matlhapolosa"
+ assert pofile.translate("bla") is None
+ unit = pofile.units[0]
+ locations = unit.getlocations()
+ assert len(locations) == 2
+ assert "example.c:123" in locations
+ assert "place.py" in locations
+
+ def test_fuzzy(self):
+ """Tests fuzzyness"""
+ minixlf = self.xliffskeleton % '''<trans-unit approved="no">
+ <source>book</source>
+ </trans-unit>
+ <trans-unit id="2" approved="yes">
+ <source>nonsense</source>
+ <target>matlhapolosa</target>
+ </trans-unit>
+ <trans-unit id="2" approved="no">
+ <source>verb</source>
+ <target state="needs-review-translation">lediri</target>
+ </trans-unit>'''
+ pofile = self.xliff2po(minixlf)
+ assert pofile.translate("nonsense") == "matlhapolosa"
+ assert pofile.translate("verb") == "lediri"
+ assert pofile.translate("book") is None
+ assert pofile.translate("bla") is None
+ assert len(pofile.units) == 3
+ #TODO: decide if this one should be fuzzy:
+ #assert pofile.units[0].isfuzzy()
+ assert not pofile.units[1].isfuzzy()
+ assert pofile.units[2].isfuzzy()
+
+ def test_plurals(self):
+ """Tests fuzzyness"""
+ minixlf = self.xliffskeleton % '''<group id="1" restype="x-gettext-plurals">
+ <trans-unit id="1[0]" xml:space="preserve">
+ <source>cow</source>
+ <target>inkomo</target>
+ </trans-unit>
+ <trans-unit id="1[1]" xml:space="preserve">
+ <source>cows</source>
+ <target>iinkomo</target>
+ </trans-unit>
+</group>'''
+ pofile = self.xliff2po(minixlf)
+ print str(pofile)
+ potext = str(pofile)
+ assert len(pofile.units) == 1
+ assert potext.index('msgid_plural "cows"')
+ assert potext.index('msgstr[0] "inkomo"')
+ assert potext.index('msgstr[1] "iinkomo"')
+
+
+class TestBasicXLIFF2PO(TestXLIFF2PO):
+ """This tests a basic XLIFF file without xmlns attribute"""
+
+ xliffskeleton = '''<?xml version="1.0" ?>
+<xliff version="1.1">
+ <file original="filename.po" source-language="en-US" datatype="po">
+ <body>
+ %s
+ </body>
+ </file>
+</xliff>'''
diff --git a/translate-toolkit-1.5.1/translate/convert/tiki2po b/translate-toolkit-1.5.1/translate/convert/tiki2po
new file mode 100644
index 0000000..56a5c44
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/tiki2po
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Mozilla Corporation, Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""simple script to convert a TikiWiki style language.php file to a gettext .po localization file"""
+
+from translate.convert import tiki2po
+
+if __name__ == '__main__':
+ tiki2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/tiki2po.py b/translate-toolkit-1.5.1/translate/convert/tiki2po.py
new file mode 100644
index 0000000..c9f768f
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/tiki2po.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 Mozilla Corporation, Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+""" Convert TikiWiki's language.php files to GetText PO files. """
+
+import re
+import sys
+from translate.storage import tiki
+from translate.storage import po
+
+class tiki2po:
+ def __init__(self, includeunused=False):
+ """
+ @param includeunused: On conversion, should the "unused" section be preserved? Default: False
+ """
+ self.includeunused = includeunused
+
+ def convertstore(self, thetikifile):
+ """Converts a given (parsed) tiki file to a po file.
+
+ @param thetikifile: a tikifile pre-loaded with input data
+ """
+ thetargetfile = po.pofile()
+
+ # Set up the header
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit")
+ thetargetfile.addunit(targetheader)
+
+ # For each lang unit, make the new po unit accordingly
+ for unit in thetikifile.units:
+ if not self.includeunused and "unused" in unit.getlocations():
+ continue
+ newunit = po.pounit()
+ newunit.source = unit.source
+ newunit.settarget(unit.target)
+ locations = unit.getlocations()
+ if locations:
+ newunit.addlocations(locations)
+ thetargetfile.addunit(newunit)
+ return thetargetfile
+
+def converttiki(inputfile, outputfile, template=None, includeunused=False):
+ """Converts from tiki file format to po.
+
+ @param inputfile: file handle of the source
+ @param outputfile: file handle to write to
+ @param template: unused
+ @param includeunused: Include the "usused" section of the tiki file? Default: False
+ """
+ convertor = tiki2po(includeunused=includeunused)
+ inputstore = tiki.TikiStore(inputfile)
+ outputstore = convertor.convertstore(inputstore)
+ if outputstore.isempty():
+ return False
+ outputfile.write(str(outputstore))
+ return True
+
+def main(argv=None):
+ """Converts tiki .php files to .po."""
+ from translate.convert import convert
+ from translate.misc import stdiotell
+ sys.stdout = stdiotell.StdIOWrapper(sys.stdout)
+
+ formats = {"php":("po",converttiki)}
+
+ parser = convert.ConvertOptionParser(formats, description=__doc__)
+ parser.add_option("", "--include-unused", dest="includeunused", action="store_true", default=False, help="Include strings in the unused section")
+ parser.passthrough.append("includeunused")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/ts2po b/translate-toolkit-1.5.1/translate/convert/ts2po
new file mode 100755
index 0000000..4837430
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/ts2po
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Converts Qt .ts localization files to Gettext .po files
+You can convert back to .ts using po2ts"""
+
+from translate.convert import ts2po
+
+if __name__ == '__main__':
+ ts2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/ts2po.py b/translate-toolkit-1.5.1/translate/convert/ts2po.py
new file mode 100644
index 0000000..372f219
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/ts2po.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert Qt Linguist (.ts) files to Gettext PO localization files
+
+See: http://translate.sourceforge.net/wiki/toolkit/ts2po for examples and
+usage instructions
+"""
+
+
+from translate.storage import po
+from translate.storage import ts
+
+class ts2po:
+ def __init__(self, duplicatestyle="msgctxt"):
+ self.duplicatestyle = duplicatestyle
+
+ def convertmessage(self, contextname, messagenum, source, target, msgcomments, transtype):
+ """makes a pounit from the given message"""
+ thepo = po.pounit(encoding="UTF-8")
+ thepo.addlocation("%s#%d" % (contextname, messagenum))
+ thepo.source = source
+ thepo.target = target
+ if len(msgcomments) > 0:
+ thepo.addnote(msgcomments)
+ if transtype == "unfinished" and thepo.istranslated():
+ thepo.markfuzzy()
+ if transtype == "obsolete":
+ # This should use the Gettext obsolete method but it would require quite a bit of work
+ thepo.addnote("(obsolete)", origin="developer")
+ # using the fact that -- quote -- "(this is nonsense)"
+ return thepo
+
+ def convertfile(self, inputfile):
+ """converts a .ts file to .po format"""
+ tsfile = ts.QtTsParser(inputfile)
+ thetargetfile = po.pofile()
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit")
+ thetargetfile.addunit(targetheader)
+ for contextname, messages in tsfile.iteritems():
+ messagenum = 0
+ for message in messages:
+ messagenum += 1
+ source = tsfile.getmessagesource(message)
+ translation = tsfile.getmessagetranslation(message)
+ comment = tsfile.getmessagecomment(message)
+ transtype = tsfile.getmessagetype(message)
+ thepo = self.convertmessage(contextname, messagenum, source, translation, comment, transtype)
+ thetargetfile.addunit(thepo)
+ thetargetfile.removeduplicates(self.duplicatestyle)
+ return thetargetfile
+
+def convertts(inputfile, outputfile, templates, duplicatestyle="msgctxt"):
+ """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout"""
+ convertor = ts2po(duplicatestyle=duplicatestyle)
+ outputstore = convertor.convertfile(inputfile)
+ if outputstore.isempty():
+ return 0
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"ts":("po", convertts)}
+ parser = convert.ConvertOptionParser(formats, usepots=True, description=__doc__)
+ parser.add_duplicates_option()
+ parser.run(argv)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/txt2po b/translate-toolkit-1.5.1/translate/convert/txt2po
new file mode 100755
index 0000000..6df4f44
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/txt2po
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Converts plain text files to Gettext .po files
+You can convert back to .txt using po2txt"""
+
+from translate.convert import txt2po
+
+if __name__ == '__main__':
+ txt2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/txt2po.py b/translate-toolkit-1.5.1/translate/convert/txt2po.py
new file mode 100644
index 0000000..d16ab2a
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/txt2po.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert plain text (.txt) files to Gettext PO localization files
+
+See: http://translate.sourceforge.net/wiki/toolkit/txt2po for examples and
+usage instructions
+"""
+
+from translate.storage import txt
+from translate.storage import po
+
+class txt2po:
+ def __init__(self, duplicatestyle="msgctxt"):
+ self.duplicatestyle = duplicatestyle
+
+ def convertstore(self, thetxtfile):
+ """converts a file to .po format"""
+ thetargetfile = po.pofile()
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit")
+ targetheader.addnote("extracted from %s" % thetxtfile.filename, "developer")
+ thetargetfile.addunit(targetheader)
+ for txtunit in thetxtfile.units:
+ newunit = thetargetfile.addsourceunit(txtunit.source)
+ newunit.addlocations(txtunit.getlocations())
+ thetargetfile.removeduplicates(self.duplicatestyle)
+ return thetargetfile
+
+def converttxt(inputfile, outputfile, templates, duplicatestyle="msgctxt", encoding="utf-8", flavour=None):
+ """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout"""
+ inputstore = txt.TxtFile(inputfile, encoding=encoding, flavour=flavour)
+ convertor = txt2po(duplicatestyle=duplicatestyle)
+ outputstore = convertor.convertstore(inputstore)
+ if outputstore.isempty():
+ return 0
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ from translate.misc import stdiotell
+ import sys
+ sys.stdout = stdiotell.StdIOWrapper(sys.stdout)
+ formats = {"txt":("po", converttxt), "*":("po", converttxt)}
+ parser = convert.ConvertOptionParser(formats, usepots=True, description=__doc__)
+ parser.add_option("", "--encoding", dest="encoding", default='utf-8', type="string",
+ help="The encoding of the input file (default: UTF-8)")
+ parser.passthrough.append("encoding")
+ parser.add_option("", "--flavour", dest="flavour", default="plain",
+ type="choice", choices=["plain", "dokuwiki", "mediawiki"],
+ help="The flavour of text file: plain (default), dokuwiki, mediawiki",
+ metavar="FLAVOUR")
+ parser.passthrough.append("flavour")
+ parser.add_duplicates_option()
+ parser.run(argv)
+
diff --git a/translate-toolkit-1.5.1/translate/convert/web2py2po b/translate-toolkit-1.5.1/translate/convert/web2py2po
new file mode 100755
index 0000000..7eaa514
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/web2py2po
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2009 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+"""convert web2py translation dictionaries (.py) to GNU/gettext PO files"""
+
+from translate.convert import web2py2po
+
+if __name__ == '__main__':
+ web2py2po.main()
diff --git a/translate-toolkit-1.5.1/translate/convert/web2py2po.py b/translate-toolkit-1.5.1/translate/convert/web2py2po.py
new file mode 100644
index 0000000..91da183
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/web2py2po.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2009 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# (c) 2009 Dominic König (dominic@nursix.org)
+#
+
+"""convert web2py translation dictionaries (.py) to GNU/gettext PO files"""
+
+import sys
+from translate.storage import po
+
+class web2py2po:
+ def __init__(self, pofile=None):
+ self.mypofile = pofile
+
+ def convertunit(self, source_str, target_str):
+ pounit = po.pounit(encoding="UTF-8")
+ pounit.setsource( source_str )
+ if target_str:
+ pounit.settarget( target_str )
+ return pounit
+
+ def convertstore(self, mydict):
+
+ targetheader = self.mypofile.makeheader(charset="UTF-8", encoding="8bit")
+ targetheader.addnote("extracted from web2py", "developer")
+
+ self.mypofile.addunit(targetheader)
+
+ for source_str in mydict.keys():
+ target_str = mydict[source_str]
+ if target_str.startswith('*** '):
+ target_str = ''
+ pounit = self.convertunit(source_str, target_str)
+ self.mypofile.addunit(pounit)
+
+ return self.mypofile
+
+def convertpy(inputfile, outputfile, encoding="UTF-8"):
+
+ new_pofile = po.pofile()
+ convertor = web2py2po(new_pofile)
+
+ mydict = eval(inputfile.read())
+ if not isinstance(mydict, dict):
+ return 0
+
+ outputstore = convertor.convertstore(mydict)
+
+ if outputstore.isempty():
+ return 0
+
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {("py", "po"): ("po", convertpy), ("py", None): ("po", convertpy)}
+ parser = convert.ConvertOptionParser(formats, usetemplates=False, description=__doc__)
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/xliff2odf b/translate-toolkit-1.5.1/translate/convert/xliff2odf
new file mode 100755
index 0000000..02c28ee
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/xliff2odf
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+#
+# Copyright 2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Takes an ODF template file and an XLIFF file containing translations of
+strings in the ODF template. It creates a new ODF file using the translations
+of the XLIFF file.
+
+Files supported include:
+- .odt (Wordprocessor documents)
+- .ods (Spreadsheets)
+- .odp (Presentations)
+- .sxw (old OpenOffice.org 1.0 Wordprocessor documents)
+"""
+
+from translate.convert import xliff2odf
+
+if __name__ == '__main__':
+ xliff2odf.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/xliff2odf.py b/translate-toolkit-1.5.1/translate/convert/xliff2odf.py
new file mode 100644
index 0000000..9f562d6
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/xliff2odf.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert OpenDocument (ODF) files to Gettext PO localization files"""
+
+import cStringIO
+import zipfile
+import re
+
+import lxml.etree as etree
+
+from translate.storage import factory
+from translate.storage.xml_extract import unit_tree
+from translate.storage.xml_extract import extract
+from translate.storage.xml_extract import generate
+from translate.storage import odf_shared, odf_io
+
+def first_child(unit_node):
+ return unit_node.children.values()[0]
+
+def translate_odf(template, input_file):
+ def load_dom_trees(template):
+ odf_data = odf_io.open_odf(template)
+ return dict((filename, etree.parse(cStringIO.StringIO(data))) for filename, data in odf_data.iteritems())
+
+ def load_unit_tree(input_file, dom_trees):
+ store = factory.getobject(input_file)
+ tree = unit_tree.build_unit_tree(store)
+
+ def extract_unit_tree(filename, root_dom_element_name):
+ """Find the subtree in 'tree' which corresponds to the data in XML file 'filename'"""
+ def get_tree():
+ try:
+ return tree.children['office:%s' % root_dom_element_name, 0]
+ except KeyError:
+ return unit_tree.XPathTree()
+ return (filename, get_tree())
+
+ return dict([extract_unit_tree('content.xml', 'document-content'),
+ extract_unit_tree('meta.xml', 'document-meta'),
+ extract_unit_tree('styles.xml', 'document-styles')])
+
+ def translate_dom_trees(unit_trees, dom_trees):
+ make_parse_state = lambda: extract.ParseState(odf_shared.no_translate_content_elements, odf_shared.inline_elements)
+ for filename, dom_tree in dom_trees.iteritems():
+ file_unit_tree = unit_trees[filename]
+ generate.apply_translations(dom_tree.getroot(), file_unit_tree, generate.replace_dom_text(make_parse_state))
+ return dom_trees
+
+ # Since the convertoptionsparser will give us an open file, we risk that
+ # it could have been opened in non-binary mode on Windows, and then we'll
+ # have problems, so let's make sure we have what we want.
+ template.close()
+ template = file(template.name, mode='rb')
+ dom_trees = load_dom_trees(template)
+ unit_trees = load_unit_tree(input_file, dom_trees)
+ return translate_dom_trees(unit_trees, dom_trees)
+
+def write_odf(xlf_data, template, output_file, dom_trees):
+ def write_content_to_odf(output_zip, dom_trees):
+ for filename, dom_tree in dom_trees.iteritems():
+ output_zip.writestr(filename, etree.tostring(dom_tree, encoding='UTF-8', xml_declaration=True))
+
+ # Since the convertoptionsparser will give us an open file, we risk that
+ # it could have been opened in non-binary mode on Windows, and then we'll
+ # have problems, so let's make sure we have what we want.
+ template.close()
+ template = file(template.name, mode='rb')
+ template_zip = zipfile.ZipFile(template, 'r')
+ output_file.close()
+ output_file = file(output_file.name, mode='wb')
+ output_zip = zipfile.ZipFile(output_file, 'w', compression=zipfile.ZIP_DEFLATED)
+ output_zip = odf_io.copy_odf(template_zip, output_zip, dom_trees.keys() + ['META-INF/manifest.xml'])
+ output_zip = odf_io.add_file(output_zip, template_zip.read('META-INF/manifest.xml'), 'translation.xlf', xlf_data)
+ write_content_to_odf(output_zip, dom_trees)
+
+def convertxliff(input_file, output_file, template):
+ """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout"""
+ xlf_data = input_file.read()
+ dom_trees = translate_odf(template, cStringIO.StringIO(xlf_data))
+ write_odf(xlf_data, template, output_file, dom_trees)
+ output_file.close()
+ return True
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"xlf": ("odt", convertxliff), # Text
+ "xlf": ("ods", convertxliff), # Spreadsheet
+ "xlf": ("odp", convertxliff), # Presentation
+ "xlf": ("odg", convertxliff), # Drawing
+ "xlf": ("odc", convertxliff), # Chart
+ "xlf": ("odf", convertxliff), # Formula
+ "xlf": ("odi", convertxliff), # Image
+ "xlf": ("odm", convertxliff), # Master Document
+ "xlf": ("ott", convertxliff), # Text template
+ "xlf": ("ots", convertxliff), # Spreadsheet template
+ "xlf": ("otp", convertxliff), # Presentation template
+ "xlf": ("otg", convertxliff), # Drawing template
+ "xlf": ("otc", convertxliff), # Chart template
+ "xlf": ("otf", convertxliff), # Formula template
+ "xlf": ("oti", convertxliff), # Image template
+ "xlf": ("oth", convertxliff), # Web page template
+ }
+
+ parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__)
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/xliff2oo b/translate-toolkit-1.5.1/translate/convert/xliff2oo
new file mode 100755
index 0000000..344cedb
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/xliff2oo
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+#
+# Copyright 2002-2004 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""script that converts a .po file with translations based on a .pot file
+generated from a OpenOffice localization .oo back to the .oo (but translated)
+Uses the original .oo to do the conversion as this makes sure we don't
+leave out any unincluded stuff..."""
+
+from translate.convert import xliff2oo
+
+if __name__ == '__main__':
+ xliff2oo.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/xliff2oo.py b/translate-toolkit-1.5.1/translate/convert/xliff2oo.py
new file mode 100644
index 0000000..67a1d73
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/xliff2oo.py
@@ -0,0 +1,226 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2004-2006 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""convert XLIFF localization files to an OpenOffice.org (SDF) localization file"""
+
+import sys
+import os
+from translate.storage import oo
+from translate.storage import factory
+from translate.filters import pofilter
+from translate.filters import checks
+from translate.filters import autocorrect
+import time
+
+class reoo:
+ def __init__(self, templatefile, languages=None, timestamp=None, includefuzzy=False, long_keys=False, filteraction="exclude"):
+ """construct a reoo converter for the specified languages (timestamp=0 means leave unchanged)"""
+ # languages is a pair of language ids
+ self.long_keys = long_keys
+ self.readoo(templatefile)
+ self.languages = languages
+ self.filteraction = filteraction
+ if timestamp is None:
+ self.timestamp = time.strptime("2002-02-02 02:02:02", "%Y-%m-%d %H:%M:%S")
+ else:
+ self.timestamp = timestamp
+ if self.timestamp:
+ self.timestamp_str = time.strftime("%Y-%m-%d %H:%M:%S", self.timestamp)
+ else:
+ self.timestamp_str = None
+ self.includefuzzy = includefuzzy
+
+ def makeindex(self):
+ """makes an index of the oo keys that are used in the source file"""
+ self.index = {}
+ for ookey, theoo in self.o.ookeys.iteritems():
+ sourcekey = oo.makekey(ookey, self.long_keys)
+ self.index[sourcekey] = theoo
+
+ def readoo(self, of):
+ """read in the oo from the file"""
+ oosrc = of.read()
+ self.o = oo.oofile()
+ self.o.parse(oosrc)
+ self.makeindex()
+
+ def handleunit(self, unit):
+ # TODO: make this work for multiple columns in oo...
+ locations = unit.getlocations()
+ # technically our formats should just have one location for each entry...
+ # but we handle multiple ones just to be safe...
+ for location in locations:
+ subkeypos = location.rfind('.')
+ subkey = location[subkeypos+1:]
+ key = location[:subkeypos]
+ # this is just to handle our old system of using %s/%s:%s instead of %s/%s#%s
+ key = key.replace(':', '#')
+ # this is to handle using / instead of \ in the sourcefile...
+ key = key.replace('\\', '/')
+ key = oo.normalizefilename(key)
+ if self.index.has_key(key):
+ # now we need to replace the definition of entity with msgstr
+ theoo = self.index[key] # find the oo
+ self.applytranslation(key, subkey, theoo, unit)
+ else:
+ print >> sys.stderr, "couldn't find key %s from po in %d keys" % (key, len(self.index))
+ try:
+ sourceunitlines = str(unit)
+ if isinstance(sourceunitlines, unicode):
+ sourceunitlines = sourceunitlines.encode("utf-8")
+ print >> sys.stderr, sourceunitlines
+ except:
+ print >> sys.stderr, "error outputting source unit %r" % (str(unit),)
+
+ def applytranslation(self, key, subkey, theoo, unit):
+ """applies the translation from the source unit to the oo unit"""
+ if not self.includefuzzy and unit.isfuzzy():
+ return
+ makecopy = False
+ if self.languages is None:
+ part1 = theoo.lines[0]
+ if len(theoo.lines) > 1:
+ part2 = theoo.lines[1]
+ else:
+ makecopy = True
+ else:
+ part1 = theoo.languages[self.languages[0]]
+ if self.languages[1] in theoo.languages:
+ part2 = theoo.languages[self.languages[1]]
+ else:
+ makecopy = True
+ if makecopy:
+ part2 = oo.ooline(part1.getparts())
+ unquotedid = unit.source
+ unquotedstr = unit.target
+ # If there is no translation, we don't want to add a line
+ if len(unquotedstr.strip()) == 0:
+ return
+ if isinstance(unquotedstr, unicode):
+ unquotedstr = unquotedstr.encode("UTF-8")
+ # finally set the new definition in the oo, but not if its empty
+ if len(unquotedstr) > 0:
+ subkey = subkey.strip()
+ setattr(part2, subkey, unquotedstr)
+ # set the modified time
+ if self.timestamp_str:
+ part2.timestamp = self.timestamp_str
+ if self.languages:
+ part2.languageid = self.languages[1]
+ if makecopy:
+ theoo.addline(part2)
+
+ def convertstore(self, sourcestore):
+ self.p = sourcestore
+ # translate the strings
+ for unit in self.p.units:
+ # there may be more than one element due to msguniq merge
+ if filter.validelement(unit, self.p.filename, self.filteraction):
+ self.handleunit(unit)
+ # return the modified oo file object
+ return self.o
+
+def getmtime(filename):
+ import stat
+ return time.localtime(os.stat(filename)[stat.ST_MTIME])
+
+class oocheckfilter(pofilter.pocheckfilter):
+ def validelement(self, unit, filename, filteraction):
+ """Returns whether or not to use unit in conversion. (filename is just for error reporting)"""
+ if filteraction == "none": return True
+ filterresult = self.filterunit(unit)
+ if filterresult:
+ if filterresult != autocorrect:
+ for filtername, filtermessage in filterresult.iteritems():
+ location = unit.getlocations()[0]
+ if filtername in self.options.error:
+ print >> sys.stderr, "Error at %s::%s: %s" % (filename, location, filtermessage)
+ return not filteraction in ["exclude-all", "exclude-serious"]
+ if filtername in self.options.warning or self.options.alwayswarn:
+ print >> sys.stderr, "Warning at %s::%s: %s" % (filename, location, filtermessage)
+ return not filteraction in ["exclude-all"]
+ return True
+
+class oofilteroptions:
+ error = ['variables', 'xmltags', 'escapes']
+ warning = ['blank']
+ #To only issue warnings for tests listed in warning, change the following to False:
+ alwayswarn = True
+ limitfilters = error + warning
+ #To use all available tests, uncomment the following:
+ #limitfilters = []
+ #To exclude certain tests, list them in here:
+ excludefilters = {}
+ includefuzzy = False
+ includereview = False
+ includeheader = False
+ autocorrect = False
+
+options = oofilteroptions()
+filter = oocheckfilter(options, [checks.OpenOfficeChecker, checks.StandardUnitChecker], checks.openofficeconfig)
+
+def convertoo(inputfile, outputfile, templatefile, sourcelanguage=None, targetlanguage=None, timestamp=None, includefuzzy=False, multifilestyle="single", filteraction=None):
+ inputstore = factory.getobject(inputfile)
+ inputstore.filename = getattr(inputfile, 'name', '')
+ if not targetlanguage:
+ raise ValueError("You must specify the target language")
+ if not sourcelanguage:
+ if targetlanguage.isdigit():
+ sourcelanguage = "01"
+ else:
+ sourcelanguage = "en-US"
+ languages = (sourcelanguage, targetlanguage)
+ if templatefile is None:
+ raise ValueError("must have template file for oo files")
+ else:
+ convertor = reoo(templatefile, languages=languages, timestamp=timestamp, includefuzzy=includefuzzy, long_keys=multifilestyle != "single", filteraction=filteraction)
+ outputstore = convertor.convertstore(inputstore)
+ # TODO: check if we need to manually delete missing items
+ outputfile.write(str(outputstore))
+ return True
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {("po", "oo"):("oo", convertoo), ("xlf", "oo"):("oo", convertoo), ("xlf", "sdf"):("sdf", convertoo)}
+ # always treat the input as an archive unless it is a directory
+ archiveformats = {(None, "output"): oo.oomultifile, (None, "template"): oo.oomultifile}
+ parser = convert.ArchiveConvertOptionParser(formats, usetemplates=True, description=__doc__, archiveformats=archiveformats)
+ parser.add_option("-l", "--language", dest="targetlanguage", default=None,
+ help="set target language code (e.g. af-ZA) [required]", metavar="LANG")
+ parser.add_option("", "--source-language", dest="sourcelanguage", default=None,
+ help="set source language code (default en-US)", metavar="LANG")
+ parser.add_option("-T", "--keeptimestamp", dest="timestamp", default=None, action="store_const", const=0,
+ help="don't change the timestamps of the strings")
+ parser.add_option("", "--nonrecursiveoutput", dest="allowrecursiveoutput", default=True, action="store_false", help="don't treat the output oo as a recursive store")
+ parser.add_option("", "--nonrecursivetemplate", dest="allowrecursivetemplate", default=True, action="store_false", help="don't treat the template oo as a recursive store")
+ parser.add_option("", "--filteraction", dest="filteraction", default="none", metavar="ACTION",
+ help="action on pofilter failure: none (default), warn, exclude-serious, exclude-all")
+ parser.add_fuzzy_option()
+ parser.add_multifile_option()
+ parser.passthrough.append("sourcelanguage")
+ parser.passthrough.append("targetlanguage")
+ parser.passthrough.append("timestamp")
+ parser.passthrough.append("filteraction")
+ parser.run(argv)
+
+if __name__ == '__main__':
+ main()
diff --git a/translate-toolkit-1.5.1/translate/convert/xliff2po b/translate-toolkit-1.5.1/translate/convert/xliff2po
new file mode 100755
index 0000000..2a89eee
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/xliff2po
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# Copyright 2005 Zuza Software Foundation
+#
+# This file is part of translate.
+#
+# translate is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# translate is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with translate; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Converts .xliff localization files to Gettext .po files
+You can convert back to .xliff using po2xliff"""
+
+from translate.convert import xliff2po
+
+if __name__ == '__main__':
+ xliff2po.main()
+
diff --git a/translate-toolkit-1.5.1/translate/convert/xliff2po.py b/translate-toolkit-1.5.1/translate/convert/xliff2po.py
new file mode 100644
index 0000000..7d38575
--- /dev/null
+++ b/translate-toolkit-1.5.1/translate/convert/xliff2po.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2002-2009 Zuza Software Foundation
+#
+# This file is part of the Translate Toolkit.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+"""Convert XLIFF localization files to Gettext PO localization files.
+
+see: http://translate.sourceforge.net/wiki/toolkit/xliff2po for examples and
+usage instructions.
+"""
+
+from translate.storage import po
+from translate.storage import xliff
+from translate.misc import wStringIO
+
+class xliff2po:
+ def converttransunit(self, transunit):
+ """makes a pounit from the given transunit"""
+ thepo = po.pounit()
+
+ #Header
+ if transunit.getrestype() == "x-gettext-domain-header":
+ thepo.source = ""
+ else:
+ thepo.source = transunit.source
+ thepo.target = transunit.target
+
+ #Location comments
+ locations = transunit.getlocations()
+ if locations:
+ thepo.addlocations(locations)
+
+ #NOTE: Supporting both <context> and <note> tags in xliff files for comments
+ #Translator comments
+ trancomments = transunit.getnotes("translator")
+ if trancomments:
+ thepo.addnote(trancomments, origin="translator")
+
+ #Automatic and Developer comments
+ autocomments = transunit.getnotes("developer")
+ if autocomments:
+ thepo.addnote(autocomments, origin="developer")
+
+ #See 5.6.1 of the spec. We should not check fuzzyness, but approved attribute
+ if transunit.isfuzzy():
+ thepo.markfuzzy(True)
+
+ return thepo
+
+ def convertstore(self, inputfile):
+ """Converts a .xliff file to .po format"""
+ # XXX: The inputfile is converted to string because Pootle supplies
+ # XXX: a PootleFile object as input which cannot be sent to PoXliffFile.
+ # XXX: The better way would be to have a consistent conversion API.
+ if not isinstance(inputfile, (file, wStringIO.StringIO)):
+ inputfile = str(inputfile)
+ XliffFile = xliff.xlifffile.parsestring(inputfile)
+ thetargetfile = po.pofile()
+ targetheader = thetargetfile.makeheader(charset="UTF-8", encoding="8bit")
+ # TODO: support multiple files
+ for transunit in XliffFile.units:
+ thepo = self.converttransunit(transunit)
+ thetargetfile.addunit(thepo)
+ return thetargetfile
+
+def convertxliff(inputfile, outputfile, templates):
+ """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout"""
+ convertor = xliff2po()
+ outputstore = convertor.convertstore(inputfile)
+ if outputstore.isempty():
+ return 0
+ outputfile.write(str(outputstore))
+ return 1
+
+def main(argv=None):
+ from translate.convert import convert
+ formats = {"xlf":("po", convertxliff)}
+ parser = convert.ConvertOptionParser(formats, usepots=True, description=__doc__)
+ parser.run(argv)