annotate babel/messages/mofile.py @ 546:10de195cfb04

catalog.add() now returns the message instance (closes #245)
author fschwarz
date Sat, 19 Mar 2011 19:28:59 +0000
parents 1869978e3895
children
rev   line source
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
2 #
532
e93f68837913 Update the copyright line.
jruigrok
parents: 422
diff changeset
3 # Copyright (C) 2007-2011 Edgewall Software
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
4 # All rights reserved.
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
5 #
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
8 # are also available at http://babel.edgewall.org/wiki/License.
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
9 #
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://babel.edgewall.org/log/.
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
13
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
14 """Writing of files in the ``gettext`` MO (machine object) format.
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
15
236
bf9579c4b0ee Add more `since` tags to stuff added in trunk.
cmlenz
parents: 176
diff changeset
16 :since: version 0.9
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
17 :see: `The Format of MO Files
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
18 <http://www.gnu.org/software/gettext/manual/gettext.html#MO-Files>`_
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
19 """
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
20
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
21 import array
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
22 import struct
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
23
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
24 from babel.messages.catalog import Catalog, Message
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
25
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
26 __all__ = ['read_mo', 'write_mo']
163
2faa5dc63068 Slightly simplified CLI-frontend class.
cmlenz
parents: 162
diff changeset
27 __docformat__ = 'restructuredtext en'
2faa5dc63068 Slightly simplified CLI-frontend class.
cmlenz
parents: 162
diff changeset
28
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
29
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
30 LE_MAGIC = 0x950412deL
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
31 BE_MAGIC = 0xde120495L
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
32
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
33 def read_mo(fileobj):
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
34 """Read a binary MO file from the given file-like object and return a
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
35 corresponding `Catalog` object.
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
36
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
37 :param fileobj: the file-like object to read the MO file from
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
38 :return: a catalog object representing the parsed MO file
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
39 :rtype: `Catalog`
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
40
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
41 :note: The implementation of this function is heavily based on the
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
42 ``GNUTranslations._parse`` method of the ``gettext`` module in the
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
43 standard library.
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
44 """
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
45 catalog = Catalog()
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
46 headers = {}
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
47
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
48 filename = getattr(fileobj, 'name', '')
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
49
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
50 buf = fileobj.read()
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
51 buflen = len(buf)
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
52 unpack = struct.unpack
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
53
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
54 # Parse the .mo file header, which consists of 5 little endian 32
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
55 # bit words.
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
56 magic = unpack('<I', buf[:4])[0] # Are we big endian or little endian?
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
57 if magic == LE_MAGIC:
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
58 version, msgcount, origidx, transidx = unpack('<4I', buf[4:20])
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
59 ii = '<II'
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
60 elif magic == BE_MAGIC:
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
61 version, msgcount, origidx, transidx = unpack('>4I', buf[4:20])
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
62 ii = '>II'
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
63 else:
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
64 raise IOError(0, 'Bad magic number', filename)
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
65
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
66 # Now put all messages from the .mo file buffer into the catalog
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
67 # dictionary
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
68 for i in xrange(0, msgcount):
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
69 mlen, moff = unpack(ii, buf[origidx:origidx + 8])
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
70 mend = moff + mlen
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
71 tlen, toff = unpack(ii, buf[transidx:transidx + 8])
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
72 tend = toff + tlen
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
73 if mend < buflen and tend < buflen:
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
74 msg = buf[moff:mend]
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
75 tmsg = buf[toff:tend]
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
76 else:
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
77 raise IOError(0, 'File is corrupt', filename)
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
78
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
79 # See if we're looking at GNU .mo conventions for metadata
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
80 if mlen == 0:
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
81 # Catalog description
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
82 lastkey = key = None
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
83 for item in tmsg.splitlines():
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
84 item = item.strip()
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
85 if not item:
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
86 continue
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
87 if ':' in item:
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
88 key, value = item.split(':', 1)
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
89 lastkey = key = key.strip().lower()
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
90 headers[key] = value.strip()
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
91 elif lastkey:
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
92 headers[lastkey] += '\n' + item
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
93
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
94 if '\x04' in msg: # context
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
95 ctxt, msg = msg.split('\x04')
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
96 else:
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
97 ctxt = None
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
98
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
99 if '\x00' in msg: # plural forms
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
100 msg = msg.split('\x00')
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
101 tmsg = tmsg.split('\x00')
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
102 if catalog.charset:
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
103 msg = [x.decode(catalog.charset) for x in msg]
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
104 tmsg = [x.decode(catalog.charset) for x in tmsg]
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
105 else:
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
106 if catalog.charset:
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
107 msg = msg.decode(catalog.charset)
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
108 tmsg = tmsg.decode(catalog.charset)
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
109 catalog[msg] = Message(msg, tmsg, context=ctxt)
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
110
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
111 # advance to next entry in the seek tables
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
112 origidx += 8
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
113 transidx += 8
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
114
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
115 catalog.mime_headers = headers.items()
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
116 return catalog
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
117
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
118 def write_mo(fileobj, catalog, use_fuzzy=False):
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
119 """Write a catalog to the specified file-like object using the GNU MO file
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
120 format.
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
121
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
122 >>> from babel.messages import Catalog
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
123 >>> from gettext import GNUTranslations
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
124 >>> from StringIO import StringIO
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
125
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
126 >>> catalog = Catalog(locale='en_US')
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
127 >>> catalog.add('foo', 'Voh')
546
10de195cfb04 catalog.add() now returns the message instance (closes #245)
fschwarz
parents: 533
diff changeset
128 <Message ...>
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
129 >>> catalog.add((u'bar', u'baz'), (u'Bahr', u'Batz'))
546
10de195cfb04 catalog.add() now returns the message instance (closes #245)
fschwarz
parents: 533
diff changeset
130 <Message ...>
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
131 >>> catalog.add('fuz', 'Futz', flags=['fuzzy'])
546
10de195cfb04 catalog.add() now returns the message instance (closes #245)
fschwarz
parents: 533
diff changeset
132 <Message ...>
174
aed3b2b06d19 Fix for #28 with updated doctest.
palgarvio
parents: 163
diff changeset
133 >>> catalog.add('Fizz', '')
546
10de195cfb04 catalog.add() now returns the message instance (closes #245)
fschwarz
parents: 533
diff changeset
134 <Message ...>
176
b29bb8629a68 Extended the doctest to include tests for the fix on [176].
palgarvio
parents: 175
diff changeset
135 >>> catalog.add(('Fuzz', 'Fuzzes'), ('', ''))
546
10de195cfb04 catalog.add() now returns the message instance (closes #245)
fschwarz
parents: 533
diff changeset
136 <Message ...>
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
137 >>> buf = StringIO()
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
138
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
139 >>> write_mo(buf, catalog)
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
140 >>> buf.seek(0)
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
141 >>> translations = GNUTranslations(fp=buf)
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
142 >>> translations.ugettext('foo')
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
143 u'Voh'
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
144 >>> translations.ungettext('bar', 'baz', 1)
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
145 u'Bahr'
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
146 >>> translations.ungettext('bar', 'baz', 2)
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
147 u'Batz'
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
148 >>> translations.ugettext('fuz')
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
149 u'fuz'
174
aed3b2b06d19 Fix for #28 with updated doctest.
palgarvio
parents: 163
diff changeset
150 >>> translations.ugettext('Fizz')
aed3b2b06d19 Fix for #28 with updated doctest.
palgarvio
parents: 163
diff changeset
151 u'Fizz'
176
b29bb8629a68 Extended the doctest to include tests for the fix on [176].
palgarvio
parents: 175
diff changeset
152 >>> translations.ugettext('Fuzz')
b29bb8629a68 Extended the doctest to include tests for the fix on [176].
palgarvio
parents: 175
diff changeset
153 u'Fuzz'
b29bb8629a68 Extended the doctest to include tests for the fix on [176].
palgarvio
parents: 175
diff changeset
154 >>> translations.ugettext('Fuzzes')
b29bb8629a68 Extended the doctest to include tests for the fix on [176].
palgarvio
parents: 175
diff changeset
155 u'Fuzzes'
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
156
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
157 :param fileobj: the file-like object to write to
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
158 :param catalog: the `Catalog` instance
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
159 :param use_fuzzy: whether translations marked as "fuzzy" should be included
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
160 in the output
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
161 """
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
162 messages = list(catalog)
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
163 if not use_fuzzy:
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
164 messages[1:] = [m for m in messages[1:] if not m.fuzzy]
250
194f927d8c5a add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents: 236
diff changeset
165 messages.sort()
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
166
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
167 ids = strs = ''
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
168 offsets = []
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
169
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
170 for message in messages:
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
171 # For each string, we need size and file offset. Each string is NUL
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
172 # terminated; the NUL does not count into the size.
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
173 if message.pluralizable:
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
174 msgid = '\x00'.join([
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
175 msgid.encode(catalog.charset) for msgid in message.id
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
176 ])
175
c223445fdb82 Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents: 174
diff changeset
177 msgstrs = []
c223445fdb82 Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents: 174
diff changeset
178 for idx, string in enumerate(message.string):
c223445fdb82 Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents: 174
diff changeset
179 if not string:
332
a7dff175b14f Fix for #97, compilation of message catalogs for locales with more than two plural forms where the translations were empty was failing.
cmlenz
parents: 250
diff changeset
180 msgstrs.append(message.id[min(int(idx), 1)])
175
c223445fdb82 Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents: 174
diff changeset
181 else:
c223445fdb82 Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents: 174
diff changeset
182 msgstrs.append(string)
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
183 msgstr = '\x00'.join([
175
c223445fdb82 Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents: 174
diff changeset
184 msgstr.encode(catalog.charset) for msgstr in msgstrs
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
185 ])
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
186 else:
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
187 msgid = message.id.encode(catalog.charset)
174
aed3b2b06d19 Fix for #28 with updated doctest.
palgarvio
parents: 163
diff changeset
188 if not message.string:
aed3b2b06d19 Fix for #28 with updated doctest.
palgarvio
parents: 163
diff changeset
189 msgstr = message.id.encode(catalog.charset)
aed3b2b06d19 Fix for #28 with updated doctest.
palgarvio
parents: 163
diff changeset
190 else:
aed3b2b06d19 Fix for #28 with updated doctest.
palgarvio
parents: 163
diff changeset
191 msgstr = message.string.encode(catalog.charset)
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
192 if message.context:
422
38feb97d4934 Add support for `msgctxt`. See #54.
palgarvio
parents: 337
diff changeset
193 msgid = '\x04'.join([message.context.encode(catalog.charset),
38feb97d4934 Add support for `msgctxt`. See #54.
palgarvio
parents: 337
diff changeset
194 msgid])
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
195 offsets.append((len(ids), len(msgid), len(strs), len(msgstr)))
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
196 ids += msgid + '\x00'
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
197 strs += msgstr + '\x00'
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
198
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
199 # The header is 7 32-bit unsigned integers. We don't use hash tables, so
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
200 # the keys start right after the index tables.
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
201 keystart = 7 * 4 + 16 * len(messages)
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
202 valuestart = keystart + len(ids)
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
203
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
204 # The string table first has the list of keys, then the list of values.
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
205 # Each entry has first the size of the string, then the file offset.
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
206 koffsets = []
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
207 voffsets = []
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
208 for o1, l1, o2, l2 in offsets:
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
209 koffsets += [l1, o1 + keystart]
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
210 voffsets += [l2, o2 + valuestart]
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
211 offsets = koffsets + voffsets
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
212
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
213 fileobj.write(struct.pack('Iiiiiii',
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 332
diff changeset
214 LE_MAGIC, # magic
162
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
215 0, # version
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
216 len(messages), # number of entries
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
217 7 * 4, # start of key index
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
218 7 * 4 + len(messages) * 8, # start of value index
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
219 0, 0 # size and offset of hash table
661cb602781d Add MO file generation. Closes #21.
cmlenz
parents:
diff changeset
220 ) + array.array("i", offsets).tostring() + ids + strs)
Copyright (C) 2012-2017 Edgewall Software