2 # -*- coding: utf-8 -*-
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
10 # Full author contact details are available in file CREDITS
12 # This script takes missing translations from another set of po files and
13 # merges them into the po files in this source tree.
16 import os, re, string, sys
20 # we do unix/windows line trimming ourselves since it can happen that we
21 # are on unix, but the file has been written on windows or vice versa.
23 " Remove end of line char(s)."
24 if line[-2:-1] == '\r':
26 elif line[-1:] == '\r' or line[-1:] == '\n':
29 # file with no EOL in last line
34 " Read utf8 input file and strip lineendings."
37 line = input.readline()
41 lines.append(line.decode('UTF-8'))
46 " Extracts msgid or msgstr from lines."
49 i = lines[0].find('"')
52 msg = lines[0][i:].strip('"')
53 for i in range(1, len(lines)):
54 msg = msg + lines[i].strip('"')
58 def translate(msgid, msgstr_lines, po2):
59 msgstr = parse_msg(msgstr_lines)
62 other = po2.find(msgid)
65 if not other.translated():
68 obsolete = (msgstr_lines[0].find('#~') == 0)
69 j = msgstr_lines[0].find('"')
70 # must not assign to msgstr_lines, because that would not be seen by our caller
71 new_lines = polib.wrap(msgstr_lines[0][0:j+1] + msgstr, 76, drop_whitespace = False)
73 for i in range(0, len(new_lines)):
75 msgstr_lines.append(new_lines[i] + '"')
77 msgstr_lines.append('#~ "' + new_lines[i] + '"')
79 msgstr_lines.append('"' + new_lines[i] + '"')
83 def mergepo_polib(target, source):
85 po1 = polib.pofile(target)
86 po2 = polib.pofile(source)
87 for entry in po1.untranslated_entries():
88 other = po2.find(entry.msgid, include_obsolete_entries=True)
91 if other.translated():
92 entry.msgstr = other.msgstr
99 def mergepo_minimaldiff(target, source):
101 po2 = polib.pofile(source)
102 target_enc = polib.detect_encoding(target)
103 # for utf8 files we can use our self written parser to minimize diffs,
104 # otherwise we need to use polib
105 if target_enc != 'UTF-8':
107 po1 = open(target, 'rb')
116 for line in oldlines:
118 if line.find('"') == 0:
119 msgid_lines.append(line)
122 msgid = parse_msg(msgid_lines)
123 newlines.extend(msgid_lines)
126 if line.find('"') == 0:
127 msgstr_lines.append(line)
130 changed = changed + translate(msgid, msgstr_lines, po2)
131 newlines.extend(msgstr_lines)
134 if not in_msgid and not in_msgstr:
135 if line.find('msgid') == 0 or line.find('#~ msgid') == 0:
136 msgid_lines.append(line)
138 elif line.find('msgstr') == 0 or line.find('#~ msgstr') == 0:
139 if line.find('msgstr[') == 0 or line.find('#~ msgstr[') == 0:
140 # plural forms are not implemented
142 msgstr_lines.append(line)
145 newlines.append(line)
147 # the file ended with a msgstr
148 changed = changed + translate(msgid, msgstr_lines, po2)
149 newlines.extend(msgstr_lines)
153 # we store .po files with unix line ends in git,
154 # so do always write them even on windows
155 po1 = open(target, 'wb')
156 for line in newlines:
157 po1.write(line.encode('UTF-8') + '\n')
161 def mergepo(target, source):
162 if not os.path.exists(source):
163 sys.stderr.write('Skipping %s since %s does not exist.\n' % (target, source))
165 if not os.path.exists(target):
166 sys.stderr.write('Skipping %s since %s does not exist.\n' % (target, target))
168 sys.stderr.write('Merging %s into %s: ' % (source, target))
170 changed = mergepo_minimaldiff(target, source)
172 changed = mergepo_polib(target, source)
173 sys.stderr.write('Updated %d translations.\n' % changed)
178 toolsdir = os.path.dirname(argv[0])
179 podir1 = os.path.normpath(os.path.join(toolsdir, '../../po'))
181 sys.stderr.write('''Usage: %s <dir> [lang] where dir is a directory containing the .po
182 files you want to take missing translations from. If lang is not given, all languages
183 are translated, otherwise only lang.\n''' % (argv[0]))
184 podir2 = os.path.abspath(argv[1])
187 name = argv[2] + '.po'
188 mergepo(os.path.join(podir1, name), os.path.join(podir2, name))
190 for i in os.listdir(podir1):
191 (base, ext) = os.path.splitext(i)
194 mergepo(os.path.join(podir1, i), os.path.join(podir2, i))
199 if __name__ == "__main__":