annotate 0.9.x/babel/messages/mofile.py @ 348:05975a0e7021 stable

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