| LEFT | RIGHT |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
| 3 # | 3 # |
| 4 # Copyright 2002-2007 Zuza Software Foundation | 4 # Copyright 2002-2007 Zuza Software Foundation |
| 5 # | 5 # |
| 6 # This file is part of translate. | 6 # This file is part of translate. |
| 7 # | 7 # |
| 8 # translate is free software; you can redistribute it and/or modify | 8 # translate is free software; you can redistribute it and/or modify |
| 9 # it under the terms of the GNU General Public License as published by | 9 # it under the terms of the GNU General Public License as published by |
| 10 # the Free Software Foundation; either version 2 of the License, or | 10 # the Free Software Foundation; either version 2 of the License, or |
| 11 # (at your option) any later version. | 11 # (at your option) any later version. |
| 12 # | 12 # |
| 13 # translate is distributed in the hope that it will be useful, | 13 # translate is distributed in the hope that it will be useful, |
| 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 # GNU General Public License for more details. | 16 # GNU General Public License for more details. |
| 17 # | 17 # |
| 18 # You should have received a copy of the GNU General Public License | 18 # You should have received a copy of the GNU General Public License |
| 19 # along with translate; if not, write to the Free Software | 19 # along with translate; if not, write to the Free Software |
| 20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 | 21 |
| 22 """classes that hold units of .po files (pounit) or entire files (pofile) | 22 """classes that hold units of .po files (pounit) or entire files (pofile) |
| 23 gettext-style .po (or .pot) files are used in translations for KDE et al (see kb
abel)""" | 23 gettext-style .po (or .pot) files are used in translations for KDE et al (see kb
abel)""" |
| 24 | 24 |
| 25 from __future__ import generators | 25 from __future__ import generators |
| 26 from translate.misc.multistring import multistring | 26 from translate.misc.multistring import multistring |
| 27 from translate.misc import quote | 27 from translate.misc import quote |
| 28 from translate.misc import textwrap | 28 from translate.misc import textwrap |
| 29 from translate.lang import data | 29 from translate.lang import data |
| 30 from translate.storage import pocommon, base | 30 from translate.storage import pocommon, base |
| 31 import re | 31 import re |
| 32 | 32 |
| 33 lsep = "\n#: " | 33 lsep = "\n#: " |
| 34 """Seperator for #: entries""" | 34 """Seperator for #: entries""" |
| 35 | 35 |
| 36 # general functions for quoting / unquoting po strings | 36 # general functions for quoting / unquoting po strings |
| 37 | 37 |
| 38 po_unescape_map = {"\\r": "\r", "\\t": "\t", '\\"': '"', '\\n': '\n', '\\\\': '\
\'} | 38 po_unescape_map = {"\\r": "\r", "\\t": "\t", '\\"': '"', '\\n': '\n', '\\\\': '\
\'} |
| 39 po_escape_map = dict([(value, key) for (key, value) in po_unescape_map.items()]) | 39 po_escape_map = dict([(value, key) for (key, value) in po_unescape_map.items()]) |
| 40 | 40 |
| 41 def escapeforpo(line): | 41 def escapeforpo(line): |
| 42 """Escapes a line for po format. assumes no \n occurs in the line. | 42 """Escapes a line for po format. assumes no \n occurs in the line. |
| 43 | 43 |
| 44 @param line: unescaped text | 44 @param line: unescaped text |
| 45 """ | 45 """ |
| 46 special_locations = [] | 46 special_locations = [] |
| 47 for special_key in po_escape_map: | 47 for special_key in po_escape_map: |
| 48 special_locations.extend(quote.find_all(line, special_key)) | 48 special_locations.extend(quote.find_all(line, special_key)) |
| 49 special_locations = dict.fromkeys(special_locations).keys() | 49 special_locations = dict.fromkeys(special_locations).keys() |
| 50 special_locations.sort() | 50 special_locations.sort() |
| (...skipping 860 matching lines...) Show 10 above Show 10 below |
| 911 output = self._getoutput() | 911 output = self._getoutput() |
| 912 if isinstance(output, unicode): | 912 if isinstance(output, unicode): |
| 913 return output.encode(getattr(self, "encoding", "UTF-8")) | 913 return output.encode(getattr(self, "encoding", "UTF-8")) |
| 914 return output | 914 return output |
| 915 | 915 |
| 916 def _getoutput(self): | 916 def _getoutput(self): |
| 917 """convert the units back to lines""" | 917 """convert the units back to lines""" |
| 918 lines = [] | 918 lines = [] |
| 919 for unit in self.units: | 919 for unit in self.units: |
| 920 unitsrc = str(unit) + "\n" | 920 unitsrc = str(unit) + "\n" |
| 921 lines.append(unitsrc) | 921 lines.append(unitsrc) |
| 922 lines = "".join(self.encode(lines)).rstrip() | 922 lines = "".join(self.encode(lines)).rstrip() |
| 923 #After the last pounit we will have \n\n and we only want to end in \n: | 923 #After the last pounit we will have \n\n and we only want to end in \n: |
| 924 if lines: lines += "\n" | 924 if lines: lines += "\n" |
| 925 return lines | 925 return lines |
| 926 | 926 |
| 927 def encode(self, lines): | 927 def encode(self, lines): |
| 928 """encode any unicode strings in lines in self._encoding""" | 928 """encode any unicode strings in lines in self._encoding""" |
| 929 newlines = [] | 929 newlines = [] |
| 930 encoding = self._encoding | 930 encoding = self._encoding |
| 931 if encoding is None or encoding.lower() == "charset": | 931 if encoding is None or encoding.lower() == "charset": |
| 932 encoding = 'UTF-8' | 932 encoding = 'UTF-8' |
| 933 for line in lines: | 933 for line in lines: |
| 934 if isinstance(line, unicode): | 934 if isinstance(line, unicode): |
| 935 line = line.encode(encoding) | 935 line = line.encode(encoding) |
| 936 newlines.append(line) | 936 newlines.append(line) |
| 937 return newlines | 937 return newlines |
| 938 | 938 |
| 939 def decode(self, lines): | 939 def decode(self, lines): |
| 940 """decode any non-unicode strings in lines with self._encoding""" | 940 """decode any non-unicode strings in lines with self._encoding""" |
| 941 newlines = [] | 941 newlines = [] |
| 942 for line in lines: | 942 for line in lines: |
| 943 if isinstance(line, str) and self._encoding is not None and self._en
coding.lower() != "charset": | 943 if isinstance(line, str) and self._encoding is not None and self._en
coding.lower() != "charset": |
| 944 try: | 944 try: |
| 945 line = line.decode(self._encoding) | 945 line = line.decode(self._encoding) |
| 946 except UnicodeError, e: | 946 except UnicodeError, e: |
| 947 raise UnicodeError("Error decoding line with encoding %r: %s
. Line is %r" % (self._encoding, e, line)) | 947 raise UnicodeError("Error decoding line with encoding %r: %s
. Line is %r" % (self._encoding, e, line)) |
| 948 newlines.append(line) | 948 newlines.append(line) |
| 949 return newlines | 949 return newlines |
| 950 | 950 |
| 951 def unit_iter(self): | 951 def unit_iter(self): |
| 952 for unit in self.units: | 952 for unit in self.units: |
| 953 if not (unit.isheader() or unit.isobsolete()): | 953 if not (unit.isheader() or unit.isobsolete()): |
| 954 yield unit | 954 yield unit |
| 955 | 955 |
| 956 if __name__ == '__main__': | 956 if __name__ == '__main__': |
| 957 import sys | 957 import sys |
| 958 pf = pofile(sys.stdin) | 958 pf = pofile(sys.stdin) |
| 959 sys.stdout.write(str(pf)) | 959 sys.stdout.write(str(pf)) |
| 960 | 960 |
| LEFT | RIGHT |