Mercurial > babel > old > mirror
annotate babel/messages/mofile.py @ 236:bf9579c4b0ee
Add more `since` tags to stuff added in trunk.
author | cmlenz |
---|---|
date | Wed, 01 Aug 2007 14:15:35 +0000 |
parents | b29bb8629a68 |
children | 194f927d8c5a |
rev | line source |
---|---|
162 | 1 # -*- coding: utf-8 -*- |
2 # | |
3 # Copyright (C) 2007 Edgewall Software | |
4 # All rights reserved. | |
5 # | |
6 # This software is licensed as described in the file COPYING, which | |
7 # you should have received as part of this distribution. The terms | |
8 # are also available at http://babel.edgewall.org/wiki/License. | |
9 # | |
10 # This software consists of voluntary contributions made by many | |
11 # individuals. For the exact contribution history, see the revision | |
12 # history and logs, available at http://babel.edgewall.org/log/. | |
13 | |
14 """Writing of files in the ``gettext`` MO (machine object) format. | |
15 | |
236 | 16 :since: version 0.9 |
162 | 17 :see: `The Format of MO Files |
18 <http://www.gnu.org/software/gettext/manual/gettext.html#MO-Files>`_ | |
19 """ | |
20 | |
21 import array | |
22 import struct | |
23 | |
163 | 24 __all__ = ['write_mo'] |
25 __docformat__ = 'restructuredtext en' | |
26 | |
162 | 27 def write_mo(fileobj, catalog, use_fuzzy=False): |
28 """Write a catalog to the specified file-like object using the GNU MO file | |
29 format. | |
30 | |
31 >>> from babel.messages import Catalog | |
32 >>> from gettext import GNUTranslations | |
33 >>> from StringIO import StringIO | |
34 | |
35 >>> catalog = Catalog(locale='en_US') | |
36 >>> catalog.add('foo', 'Voh') | |
37 >>> catalog.add((u'bar', u'baz'), (u'Bahr', u'Batz')) | |
38 >>> catalog.add('fuz', 'Futz', flags=['fuzzy']) | |
174 | 39 >>> catalog.add('Fizz', '') |
176
b29bb8629a68
Extended the doctest to include tests for the fix on [176].
palgarvio
parents:
175
diff
changeset
|
40 >>> catalog.add(('Fuzz', 'Fuzzes'), ('', '')) |
162 | 41 >>> buf = StringIO() |
42 | |
43 >>> write_mo(buf, catalog) | |
44 >>> buf.seek(0) | |
45 >>> translations = GNUTranslations(fp=buf) | |
46 >>> translations.ugettext('foo') | |
47 u'Voh' | |
48 >>> translations.ungettext('bar', 'baz', 1) | |
49 u'Bahr' | |
50 >>> translations.ungettext('bar', 'baz', 2) | |
51 u'Batz' | |
52 >>> translations.ugettext('fuz') | |
53 u'fuz' | |
174 | 54 >>> translations.ugettext('Fizz') |
55 u'Fizz' | |
176
b29bb8629a68
Extended the doctest to include tests for the fix on [176].
palgarvio
parents:
175
diff
changeset
|
56 >>> translations.ugettext('Fuzz') |
b29bb8629a68
Extended the doctest to include tests for the fix on [176].
palgarvio
parents:
175
diff
changeset
|
57 u'Fuzz' |
b29bb8629a68
Extended the doctest to include tests for the fix on [176].
palgarvio
parents:
175
diff
changeset
|
58 >>> translations.ugettext('Fuzzes') |
b29bb8629a68
Extended the doctest to include tests for the fix on [176].
palgarvio
parents:
175
diff
changeset
|
59 u'Fuzzes' |
162 | 60 |
61 :param fileobj: the file-like object to write to | |
62 :param catalog: the `Catalog` instance | |
63 :param use_fuzzy: whether translations marked as "fuzzy" should be included | |
64 in the output | |
65 """ | |
66 messages = list(catalog) | |
67 if not use_fuzzy: | |
68 messages[1:] = [m for m in messages[1:] if not m.fuzzy] | |
69 messages.sort(lambda x,y: cmp(x.id, y.id)) | |
70 | |
71 ids = strs = '' | |
72 offsets = [] | |
73 | |
74 for message in messages: | |
75 # For each string, we need size and file offset. Each string is NUL | |
76 # terminated; the NUL does not count into the size. | |
77 if message.pluralizable: | |
78 msgid = '\x00'.join([ | |
79 msgid.encode(catalog.charset) for msgid in message.id | |
80 ]) | |
175
c223445fdb82
Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents:
174
diff
changeset
|
81 msgstrs = [] |
c223445fdb82
Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents:
174
diff
changeset
|
82 for idx, string in enumerate(message.string): |
c223445fdb82
Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents:
174
diff
changeset
|
83 if not string: |
c223445fdb82
Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents:
174
diff
changeset
|
84 msgstrs.append(message.id[idx]) |
c223445fdb82
Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents:
174
diff
changeset
|
85 else: |
c223445fdb82
Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents:
174
diff
changeset
|
86 msgstrs.append(string) |
162 | 87 msgstr = '\x00'.join([ |
175
c223445fdb82
Forgot to fix the pluralizable messages, regarding #28.
palgarvio
parents:
174
diff
changeset
|
88 msgstr.encode(catalog.charset) for msgstr in msgstrs |
162 | 89 ]) |
90 else: | |
91 msgid = message.id.encode(catalog.charset) | |
174 | 92 if not message.string: |
93 msgstr = message.id.encode(catalog.charset) | |
94 else: | |
95 msgstr = message.string.encode(catalog.charset) | |
162 | 96 offsets.append((len(ids), len(msgid), len(strs), len(msgstr))) |
97 ids += msgid + '\x00' | |
98 strs += msgstr + '\x00' | |
99 | |
100 # The header is 7 32-bit unsigned integers. We don't use hash tables, so | |
101 # the keys start right after the index tables. | |
102 keystart = 7 * 4 + 16 * len(messages) | |
103 valuestart = keystart + len(ids) | |
104 | |
105 # The string table first has the list of keys, then the list of values. | |
106 # Each entry has first the size of the string, then the file offset. | |
107 koffsets = [] | |
108 voffsets = [] | |
109 for o1, l1, o2, l2 in offsets: | |
110 koffsets += [l1, o1 + keystart] | |
111 voffsets += [l2, o2 + valuestart] | |
112 offsets = koffsets + voffsets | |
113 | |
114 fileobj.write(struct.pack('Iiiiiii', | |
115 0x950412deL, # magic | |
116 0, # version | |
117 len(messages), # number of entries | |
118 7 * 4, # start of key index | |
119 7 * 4 + len(messages) * 8, # start of value index | |
120 0, 0 # size and offset of hash table | |
121 ) + array.array("i", offsets).tostring() + ids + strs) |