annotate babel/messages/pofile.py @ 527:5e1804d27d65

Cleanup round #1: get rid of the frozenset/set utility code and imports. This is no longer needed with 2.4 and onward.
author jruigrok
date Sat, 05 Mar 2011 14:59:20 +0000
parents d2e9aaa7c91c
children e93f68837913
rev   line source
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
2 #
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
3 # Copyright (C) 2007-2008 Edgewall Software
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
4 # All rights reserved.
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
5 #
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
8 # are also available at http://babel.edgewall.org/wiki/License.
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
9 #
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://babel.edgewall.org/log/.
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
13
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
14 """Reading and writing of files in the ``gettext`` PO (portable object)
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
15 format.
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
16
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
17 :see: `The Format of PO Files
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
18 <http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files>`_
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
19 """
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
20
7
8d7b3077e6d1 * The creation-date header in generated PO files now includes the timezone offset.
cmlenz
parents: 3
diff changeset
21 from datetime import date, datetime
136
9e3d2b227ec3 More fixes for Windows compatibility:
cmlenz
parents: 122
diff changeset
22 import os
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
23 import re
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
24
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
25 from babel import __version__ as VERSION
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
26 from babel.messages.catalog import Catalog, Message
527
5e1804d27d65 Cleanup round #1: get rid of the frozenset/set utility code and imports.
jruigrok
parents: 443
diff changeset
27 from babel.util import wraptext, LOCALTZ
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
28
180
7e88950ab661 Minor change to what symbols are ?exported?, primarily for the generated docs.
cmlenz
parents: 177
diff changeset
29 __all__ = ['read_po', 'write_po']
163
2faa5dc63068 Slightly simplified CLI-frontend class.
cmlenz
parents: 160
diff changeset
30 __docformat__ = 'restructuredtext en'
160
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
31
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
32 def unescape(string):
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
33 r"""Reverse `escape` the given string.
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
34
160
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
35 >>> print unescape('"Say:\\n \\"hello, world!\\"\\n"')
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
36 Say:
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
37 "hello, world!"
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
38 <BLANKLINE>
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
39
160
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
40 :param string: the string to unescape
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
41 :return: the unescaped string
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
42 :rtype: `str` or `unicode`
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
43 """
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
44 return string[1:-1].replace('\\\\', '\\') \
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
45 .replace('\\t', '\t') \
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
46 .replace('\\r', '\r') \
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
47 .replace('\\n', '\n') \
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
48 .replace('\\"', '\"')
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
49
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
50 def denormalize(string):
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
51 r"""Reverse the normalization done by the `normalize` function.
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
52
160
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
53 >>> print denormalize(r'''""
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
54 ... "Say:\n"
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
55 ... " \"hello, world!\"\n"''')
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
56 Say:
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
57 "hello, world!"
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
58 <BLANKLINE>
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
59
160
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
60 >>> print denormalize(r'''""
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
61 ... "Say:\n"
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
62 ... " \"Lorem ipsum dolor sit "
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
63 ... "amet, consectetur adipisicing"
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
64 ... " elit, \"\n"''')
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
65 Say:
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
66 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
67 <BLANKLINE>
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
68
160
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
69 :param string: the string to denormalize
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
70 :return: the denormalized string
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
71 :rtype: `unicode` or `str`
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
72 """
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
73 if string.startswith('""'):
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
74 lines = []
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
75 for line in string.splitlines()[1:]:
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
76 lines.append(unescape(line))
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
77 return ''.join(lines)
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
78 else:
b5659b7779be Minor cleanup in the `pofile` module.
cmlenz
parents: 151
diff changeset
79 return unescape(string)
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
80
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
81 def read_po(fileobj, locale=None, domain=None, ignore_obsolete=False):
8
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
82 """Read messages from a ``gettext`` PO (portable object) file from the given
66
d1a7425739d3 `read_po` now returns a `Catalog`.
cmlenz
parents: 58
diff changeset
83 file-like object and return a `Catalog`.
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
84
8
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
85 >>> from StringIO import StringIO
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
86 >>> buf = StringIO('''
8
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
87 ... #: main.py:1
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
88 ... #, fuzzy, python-format
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
89 ... msgid "foo %(name)s"
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
90 ... msgstr ""
23
f828705c3bce Change pot header's first line, "Translations Template for %%(project)s." instead of "SOME DESCRIPTIVE TITLE.". '''`project`''' and '''`version`''' now default to '''PROJECT''' and '''VERSION''' respectively. Fixed a bug regarding '''Content-Transfer-Encoding''', it shouldn't be the charset, and we're defaulting to `8bit` untill someone complains.
palgarvio
parents: 19
diff changeset
91 ...
96
6c07c38e23aa Updated `read_po` to add user comments besides just auto comments.
palgarvio
parents: 86
diff changeset
92 ... # A user comment
6c07c38e23aa Updated `read_po` to add user comments besides just auto comments.
palgarvio
parents: 86
diff changeset
93 ... #. An auto comment
8
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
94 ... #: main.py:3
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
95 ... msgid "bar"
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
96 ... msgid_plural "baz"
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
97 ... msgstr[0] ""
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
98 ... msgstr[1] ""
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
99 ... ''')
66
d1a7425739d3 `read_po` now returns a `Catalog`.
cmlenz
parents: 58
diff changeset
100 >>> catalog = read_po(buf)
106
2a00e352c986 Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents: 105
diff changeset
101 >>> catalog.revision_date = datetime(2007, 04, 01)
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
102
66
d1a7425739d3 `read_po` now returns a `Catalog`.
cmlenz
parents: 58
diff changeset
103 >>> for message in catalog:
69
1d8e81bfedf9 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 66
diff changeset
104 ... if message.id:
1d8e81bfedf9 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 66
diff changeset
105 ... print (message.id, message.string)
107
4b42e23644e5 `Message`, `read_po` and `write_po` now all handle user/auto comments correctly.
palgarvio
parents: 106
diff changeset
106 ... print ' ', (message.locations, message.flags)
4b42e23644e5 `Message`, `read_po` and `write_po` now all handle user/auto comments correctly.
palgarvio
parents: 106
diff changeset
107 ... print ' ', (message.user_comments, message.auto_comments)
151
12e5f21dfcda Respect charset specified in PO headers in `read_po()`. Fixes #17.
cmlenz
parents: 136
diff changeset
108 (u'foo %(name)s', '')
12e5f21dfcda Respect charset specified in PO headers in `read_po()`. Fixes #17.
cmlenz
parents: 136
diff changeset
109 ([(u'main.py', 1)], set([u'fuzzy', u'python-format']))
107
4b42e23644e5 `Message`, `read_po` and `write_po` now all handle user/auto comments correctly.
palgarvio
parents: 106
diff changeset
110 ([], [])
151
12e5f21dfcda Respect charset specified in PO headers in `read_po()`. Fixes #17.
cmlenz
parents: 136
diff changeset
111 ((u'bar', u'baz'), ('', ''))
12e5f21dfcda Respect charset specified in PO headers in `read_po()`. Fixes #17.
cmlenz
parents: 136
diff changeset
112 ([(u'main.py', 3)], set([]))
12e5f21dfcda Respect charset specified in PO headers in `read_po()`. Fixes #17.
cmlenz
parents: 136
diff changeset
113 ([u'A user comment'], [u'An auto comment'])
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
114
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
115 :param fileobj: the file-like object to read the PO file from
198
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
116 :param locale: the locale identifier or `Locale` object, or `None`
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
117 if the catalog is not bound to a locale (which basically
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
118 means it's a template)
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
119 :param domain: the message domain
229
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 228
diff changeset
120 :param ignore_obsolete: whether to ignore obsolete messages in the input
336
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 317
diff changeset
121 :return: a catalog object representing the parsed PO file
6e86b862af57 Add basic MO file reading in preparation for #54.
cmlenz
parents: 317
diff changeset
122 :rtype: `Catalog`
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
123 """
198
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
124 catalog = Catalog(locale=locale, domain=domain)
66
d1a7425739d3 `read_po` now returns a `Catalog`.
cmlenz
parents: 58
diff changeset
125
198
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
126 counter = [0]
222
bd8b1301b27e Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents: 205
diff changeset
127 offset = [0]
8
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
128 messages = []
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
129 translations = []
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
130 locations = []
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
131 flags = []
107
4b42e23644e5 `Message`, `read_po` and `write_po` now all handle user/auto comments correctly.
palgarvio
parents: 106
diff changeset
132 user_comments = []
4b42e23644e5 `Message`, `read_po` and `write_po` now all handle user/auto comments correctly.
palgarvio
parents: 106
diff changeset
133 auto_comments = []
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
134 obsolete = [False]
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
135 context = []
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
136 in_msgid = [False]
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
137 in_msgstr = [False]
344
2a7b818fa5a0 Fixed a bug in pofile (in_msgctxt was not defined). Test follows.
aronacher
parents: 337
diff changeset
138 in_msgctxt = [False]
8
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
139
66
d1a7425739d3 `read_po` now returns a `Catalog`.
cmlenz
parents: 58
diff changeset
140 def _add_message():
8
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
141 translations.sort()
66
d1a7425739d3 `read_po` now returns a `Catalog`.
cmlenz
parents: 58
diff changeset
142 if len(messages) > 1:
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
143 msgid = tuple([denormalize(m) for m in messages])
66
d1a7425739d3 `read_po` now returns a `Catalog`.
cmlenz
parents: 58
diff changeset
144 else:
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
145 msgid = denormalize(messages[0])
372
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
146 if isinstance(msgid, (list, tuple)):
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
147 string = []
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
148 for idx in range(catalog.num_plurals):
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
149 try:
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
150 string.append(translations[idx])
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
151 except IndexError:
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
152 string.append((idx, ''))
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
153 string = tuple([denormalize(t[1]) for t in string])
66
d1a7425739d3 `read_po` now returns a `Catalog`.
cmlenz
parents: 58
diff changeset
154 else:
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
155 string = denormalize(translations[0][1])
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
156 if context:
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
157 msgctxt = denormalize('\n'.join(context))
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
158 else:
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
159 msgctxt = None
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
160 message = Message(msgid, string, list(locations), set(flags),
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
161 auto_comments, user_comments, lineno=offset[0] + 1,
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
162 context=msgctxt)
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
163 if obsolete[0]:
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
164 if not ignore_obsolete:
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
165 catalog.obsolete[msgid] = message
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
166 else:
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
167 catalog[msgid] = message
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
168 del messages[:]; del translations[:]; del context[:]; del locations[:];
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
169 del flags[:]; del auto_comments[:]; del user_comments[:];
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
170 obsolete[0] = False
198
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
171 counter[0] += 1
8
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
172
222
bd8b1301b27e Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents: 205
diff changeset
173 def _process_message_line(lineno, line):
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
174 if line.startswith('msgid_plural'):
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
175 in_msgid[0] = True
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
176 msg = line[12:].lstrip()
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
177 messages.append(msg)
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
178 elif line.startswith('msgid'):
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
179 in_msgid[0] = True
222
bd8b1301b27e Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents: 205
diff changeset
180 offset[0] = lineno
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
181 txt = line[5:].lstrip()
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
182 if messages:
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
183 _add_message()
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
184 messages.append(txt)
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
185 elif line.startswith('msgstr'):
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
186 in_msgid[0] = False
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
187 in_msgstr[0] = True
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
188 msg = line[6:].lstrip()
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
189 if msg.startswith('['):
443
d2e9aaa7c91c Make sure to only strip on the first occurence of ].
jruigrok
parents: 430
diff changeset
190 idx, msg = msg[1:].split(']', 1)
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
191 translations.append([int(idx), msg.lstrip()])
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
192 else:
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
193 translations.append([0, msg])
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
194 elif line.startswith('msgctxt'):
430
70f72bc70a93 Fix for msgctxt parsing in PO files. Thanks to Asheesh Laroia for the patch. Closes #159.
cmlenz
parents: 425
diff changeset
195 if messages:
70f72bc70a93 Fix for msgctxt parsing in PO files. Thanks to Asheesh Laroia for the patch. Closes #159.
cmlenz
parents: 425
diff changeset
196 _add_message()
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
197 in_msgid[0] = in_msgstr[0] = False
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
198 context.append(line[7:].lstrip())
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
199 elif line.startswith('"'):
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
200 if in_msgid[0]:
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
201 messages[-1] += u'\n' + line.rstrip()
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
202 elif in_msgstr[0]:
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
203 translations[-1][1] += u'\n' + line.rstrip()
337
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
204 elif in_msgctxt[0]:
662d332c0a2b More preparation for msgctxt support (#54).
cmlenz
parents: 336
diff changeset
205 context.append(line.rstrip())
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
206
222
bd8b1301b27e Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents: 205
diff changeset
207 for lineno, line in enumerate(fileobj.readlines()):
416
f03cc3bed4e1 fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 372
diff changeset
208 line = line.strip()
f03cc3bed4e1 fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 372
diff changeset
209 if not isinstance(line, unicode):
f03cc3bed4e1 fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 372
diff changeset
210 line = line.decode(catalog.charset)
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
211 if line.startswith('#'):
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
212 in_msgid[0] = in_msgstr[0] = False
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
213 if messages and translations:
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
214 _add_message()
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
215 if line[1:].startswith(':'):
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
216 for location in line[2:].lstrip().split():
358
c82ad0f5ff65 Fixed #59 by falling back silently on invalid location comments.
aronacher
parents: 344
diff changeset
217 pos = location.rfind(':')
c82ad0f5ff65 Fixed #59 by falling back silently on invalid location comments.
aronacher
parents: 344
diff changeset
218 if pos >= 0:
c82ad0f5ff65 Fixed #59 by falling back silently on invalid location comments.
aronacher
parents: 344
diff changeset
219 try:
c82ad0f5ff65 Fixed #59 by falling back silently on invalid location comments.
aronacher
parents: 344
diff changeset
220 lineno = int(location[pos + 1:])
c82ad0f5ff65 Fixed #59 by falling back silently on invalid location comments.
aronacher
parents: 344
diff changeset
221 except ValueError:
c82ad0f5ff65 Fixed #59 by falling back silently on invalid location comments.
aronacher
parents: 344
diff changeset
222 continue
c82ad0f5ff65 Fixed #59 by falling back silently on invalid location comments.
aronacher
parents: 344
diff changeset
223 locations.append((location[:pos], lineno))
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
224 elif line[1:].startswith(','):
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
225 for flag in line[2:].lstrip().split(','):
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
226 flags.append(flag.strip())
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
227 elif line[1:].startswith('~'):
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
228 obsolete[0] = True
222
bd8b1301b27e Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents: 205
diff changeset
229 _process_message_line(lineno, line[2:].lstrip())
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
230 elif line[1:].startswith('.'):
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
231 # These are called auto-comments
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
232 comment = line[2:].strip()
201
10e8d072e2d1 Handle obsolete messages when parsing catalogs. Closes #32.
cmlenz
parents: 198
diff changeset
233 if comment: # Just check that we're not adding empty comments
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
234 auto_comments.append(comment)
122
03f106700f02 Added tests for `new_catalog` distutils command.
cmlenz
parents: 110
diff changeset
235 else:
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
236 # These are called user comments
122
03f106700f02 Added tests for `new_catalog` distutils command.
cmlenz
parents: 110
diff changeset
237 user_comments.append(line[1:].strip())
106
2a00e352c986 Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents: 105
diff changeset
238 else:
222
bd8b1301b27e Added infrastructure for adding catalog checkers, and implement a checker that validations Python format parameters in translations, closing #19.
cmlenz
parents: 205
diff changeset
239 _process_message_line(lineno, line)
8
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
240
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
241 if messages:
66
d1a7425739d3 `read_po` now returns a `Catalog`.
cmlenz
parents: 58
diff changeset
242 _add_message()
198
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
243
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
244 # No actual messages found, but there was some info in comments, from which
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
245 # we'll construct an empty header message
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
246 elif not counter[0] and (flags or user_comments or auto_comments):
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
247 messages.append(u'')
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
248 translations.append([0, u''])
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
249 _add_message()
982d7e704fdc Fix for #35, and a minor improvement to how we parse the catalog fuzzy bit.
cmlenz
parents: 193
diff changeset
250
66
d1a7425739d3 `read_po` now returns a `Catalog`.
cmlenz
parents: 58
diff changeset
251 return catalog
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
252
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
253 WORD_SEP = re.compile('('
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
254 r'\s+|' # any whitespace
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
255 r'[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|' # hyphenated words
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
256 r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w)' # em-dash
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
257 ')')
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
258
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
259 def escape(string):
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
260 r"""Escape the given string so that it can be included in double-quoted
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
261 strings in ``PO`` files.
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
262
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
263 >>> escape('''Say:
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
264 ... "hello, world!"
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
265 ... ''')
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
266 '"Say:\\n \\"hello, world!\\"\\n"'
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
267
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
268 :param string: the string to escape
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
269 :return: the escaped string
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
270 :rtype: `str` or `unicode`
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
271 """
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
272 return '"%s"' % string.replace('\\', '\\\\') \
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
273 .replace('\t', '\\t') \
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
274 .replace('\r', '\\r') \
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
275 .replace('\n', '\\n') \
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
276 .replace('\"', '\\"')
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
277
192
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
278 def normalize(string, prefix='', width=76):
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 107
diff changeset
279 r"""Convert a string into a format that is appropriate for .po files.
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
280
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
281 >>> print normalize('''Say:
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
282 ... "hello, world!"
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
283 ... ''', width=None)
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
284 ""
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
285 "Say:\n"
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
286 " \"hello, world!\"\n"
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
287
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
288 >>> print normalize('''Say:
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
289 ... "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
290 ... ''', width=32)
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
291 ""
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
292 "Say:\n"
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
293 " \"Lorem ipsum dolor sit "
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
294 "amet, consectetur adipisicing"
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
295 " elit, \"\n"
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
296
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
297 :param string: the string to normalize
192
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
298 :param prefix: a string that should be prepended to every line
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
299 :param width: the maximum line width; use `None`, 0, or a negative number
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
300 to completely disable line wrapping
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
301 :return: the normalized string
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
302 :rtype: `unicode`
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
303 """
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
304 if width and width > 0:
192
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
305 prefixlen = len(prefix)
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
306 lines = []
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
307 for idx, line in enumerate(string.splitlines(True)):
192
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
308 if len(escape(line)) + prefixlen > width:
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
309 chunks = WORD_SEP.split(line)
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
310 chunks.reverse()
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
311 while chunks:
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
312 buf = []
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
313 size = 2
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
314 while chunks:
192
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
315 l = len(escape(chunks[-1])) - 2 + prefixlen
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
316 if size + l < width:
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
317 buf.append(chunks.pop())
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
318 size += l
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
319 else:
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
320 if not buf:
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
321 # handle long chunks by putting them on a
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
322 # separate line
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
323 buf.append(chunks.pop())
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
324 break
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
325 lines.append(u''.join(buf))
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
326 else:
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
327 lines.append(line)
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
328 else:
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
329 lines = string.splitlines(True)
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
330
69
1d8e81bfedf9 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 66
diff changeset
331 if len(lines) <= 1:
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
332 return escape(string)
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
333
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
334 # Remove empty trailing line
69
1d8e81bfedf9 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 66
diff changeset
335 if lines and not lines[-1]:
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
336 del lines[-1]
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
337 lines[-1] += '\n'
192
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
338 return u'""\n' + u'\n'.join([(prefix + escape(l)) for l in lines])
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
339
106
2a00e352c986 Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents: 105
diff changeset
340 def write_po(fileobj, catalog, width=76, no_location=False, omit_header=False,
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
341 sort_output=False, sort_by_file=False, ignore_obsolete=False,
205
aefe4ac123a2 Minor changes to how previous msgids are processed.
cmlenz
parents: 202
diff changeset
342 include_previous=False):
58
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 57
diff changeset
343 r"""Write a ``gettext`` PO (portable object) template file for a given
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 57
diff changeset
344 message catalog to the provided file-like object.
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
345
58
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 57
diff changeset
346 >>> catalog = Catalog()
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 57
diff changeset
347 >>> catalog.add(u'foo %(name)s', locations=[('main.py', 1)],
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 57
diff changeset
348 ... flags=('fuzzy',))
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 57
diff changeset
349 >>> catalog.add((u'bar', u'baz'), locations=[('main.py', 3)])
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
350 >>> from StringIO import StringIO
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
351 >>> buf = StringIO()
106
2a00e352c986 Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents: 105
diff changeset
352 >>> write_po(buf, catalog, omit_header=True)
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
353 >>> print buf.getvalue()
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
354 #: main.py:1
8
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
355 #, fuzzy, python-format
ff5481545bfd Add basic PO file parsing, and change the PO writing procedure to also take flags (such as "python-format" or "fuzzy").
cmlenz
parents: 7
diff changeset
356 msgid "foo %(name)s"
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
357 msgstr ""
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
358 <BLANKLINE>
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
359 #: main.py:3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
360 msgid "bar"
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
361 msgid_plural "baz"
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
362 msgstr[0] ""
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
363 msgstr[1] ""
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
364 <BLANKLINE>
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
365 <BLANKLINE>
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
366
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
367 :param fileobj: the file-like object to write to
69
1d8e81bfedf9 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 66
diff changeset
368 :param catalog: the `Catalog` instance
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
369 :param width: the maximum line width for the generated output; use `None`,
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
370 0, or a negative number to completely disable line wrapping
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
371 :param no_location: do not emit a location comment for every message
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
372 :param omit_header: do not include the ``msgid ""`` entry at the top of the
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
373 output
229
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 228
diff changeset
374 :param sort_output: whether to sort the messages in the output by msgid
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 228
diff changeset
375 :param sort_by_file: whether to sort the messages in the output by their
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 228
diff changeset
376 locations
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 228
diff changeset
377 :param ignore_obsolete: whether to ignore obsolete messages and not include
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 228
diff changeset
378 them in the output; by default they are included as
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 228
diff changeset
379 comments
205
aefe4ac123a2 Minor changes to how previous msgids are processed.
cmlenz
parents: 202
diff changeset
380 :param include_previous: include the old msgid as a comment when
231
fc8b8c2bba53 Remove duplicate locations of catalog messages.
cmlenz
parents: 229
diff changeset
381 updating the catalog
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
382 """
192
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
383 def _normalize(key, prefix=''):
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
384 return normalize(key, prefix=prefix, width=width) \
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
385 .encode(catalog.charset, 'backslashreplace')
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
386
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
387 def _write(text):
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
388 if isinstance(text, unicode):
104
57d2f21a1fcc Project name and version, and the charset are available via the `Catalog` object, and do not need to be passed to `write_pot()`.
cmlenz
parents: 99
diff changeset
389 text = text.encode(catalog.charset)
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
390 fileobj.write(text)
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
391
183
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
392 def _write_comment(comment, prefix=''):
425
15541acbe8cb Now, the `--width` option, although with a default value of 76, it's not set to any value initially so that the `--no-wrap` option can be passed without throwing an error. Fixes #145.
palgarvio
parents: 423
diff changeset
393 # xgettext always wraps comments even if --no-wrap is passed;
15541acbe8cb Now, the `--width` option, although with a default value of 76, it's not set to any value initially so that the `--no-wrap` option can be passed without throwing an error. Fixes #145.
palgarvio
parents: 423
diff changeset
394 # provide the same behaviour
183
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
395 if width and width > 0:
425
15541acbe8cb Now, the `--width` option, although with a default value of 76, it's not set to any value initially so that the `--no-wrap` option can be passed without throwing an error. Fixes #145.
palgarvio
parents: 423
diff changeset
396 _width = width
15541acbe8cb Now, the `--width` option, although with a default value of 76, it's not set to any value initially so that the `--no-wrap` option can be passed without throwing an error. Fixes #145.
palgarvio
parents: 423
diff changeset
397 else:
15541acbe8cb Now, the `--width` option, although with a default value of 76, it's not set to any value initially so that the `--no-wrap` option can be passed without throwing an error. Fixes #145.
palgarvio
parents: 423
diff changeset
398 _width = 76
15541acbe8cb Now, the `--width` option, although with a default value of 76, it's not set to any value initially so that the `--no-wrap` option can be passed without throwing an error. Fixes #145.
palgarvio
parents: 423
diff changeset
399 for line in wraptext(comment, _width):
183
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
400 _write('#%s %s\n' % (prefix, line.strip()))
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
401
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
402 def _write_message(message, prefix=''):
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
403 if isinstance(message.id, (list, tuple)):
423
322b257aeb3c Include patch from Asheesh Laroia. Fixes #45.
palgarvio
parents: 416
diff changeset
404 if message.context:
322b257aeb3c Include patch from Asheesh Laroia. Fixes #45.
palgarvio
parents: 416
diff changeset
405 _write('%smsgctxt %s\n' % (prefix,
322b257aeb3c Include patch from Asheesh Laroia. Fixes #45.
palgarvio
parents: 416
diff changeset
406 _normalize(message.context, prefix)))
192
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
407 _write('%smsgid %s\n' % (prefix, _normalize(message.id[0], prefix)))
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
408 _write('%smsgid_plural %s\n' % (
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
409 prefix, _normalize(message.id[1], prefix)
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
410 ))
372
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
411
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
412 for idx in range(catalog.num_plurals):
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
413 try:
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
414 string = message.string[idx]
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
415 except IndexError:
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
416 string = ''
192
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
417 _write('%smsgstr[%d] %s\n' % (
372
d1a9c618d2d5 We no longer neglect `catalog.plurals`. Added tests for it. Fixes #120.
palgarvio
parents: 358
diff changeset
418 prefix, idx, _normalize(string, prefix)
192
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
419 ))
183
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
420 else:
423
322b257aeb3c Include patch from Asheesh Laroia. Fixes #45.
palgarvio
parents: 416
diff changeset
421 if message.context:
322b257aeb3c Include patch from Asheesh Laroia. Fixes #45.
palgarvio
parents: 416
diff changeset
422 _write('%smsgctxt %s\n' % (prefix,
322b257aeb3c Include patch from Asheesh Laroia. Fixes #45.
palgarvio
parents: 416
diff changeset
423 _normalize(message.context, prefix)))
192
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
424 _write('%smsgid %s\n' % (prefix, _normalize(message.id, prefix)))
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
425 _write('%smsgstr %s\n' % (
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
426 prefix, _normalize(message.string or '', prefix)
8f5805197198 Correctly write out obsolete messages spanning multiple lines. Fixes #33.
cmlenz
parents: 183
diff changeset
427 ))
183
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
428
106
2a00e352c986 Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents: 105
diff changeset
429 messages = list(catalog)
73
5d8e87acdcc7 Implemented message sorting, see #7.
palgarvio
parents: 70
diff changeset
430 if sort_output:
250
194f927d8c5a add a __cmp__ to Message that correctly sorts by id, taking into account plurals
pjenvey
parents: 231
diff changeset
431 messages.sort()
73
5d8e87acdcc7 Implemented message sorting, see #7.
palgarvio
parents: 70
diff changeset
432 elif sort_by_file:
5d8e87acdcc7 Implemented message sorting, see #7.
palgarvio
parents: 70
diff changeset
433 messages.sort(lambda x,y: cmp(x.locations, y.locations))
70
620fdd25657a Add back POT header broken in previous check-in.
cmlenz
parents: 69
diff changeset
434
73
5d8e87acdcc7 Implemented message sorting, see #7.
palgarvio
parents: 70
diff changeset
435 for message in messages:
69
1d8e81bfedf9 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 66
diff changeset
436 if not message.id: # This is the header "message"
1d8e81bfedf9 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 66
diff changeset
437 if omit_header:
1d8e81bfedf9 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 66
diff changeset
438 continue
106
2a00e352c986 Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents: 105
diff changeset
439 comment_header = catalog.header_comment
105
abd3a594dab4 Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents: 104
diff changeset
440 if width and width > 0:
abd3a594dab4 Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents: 104
diff changeset
441 lines = []
106
2a00e352c986 Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents: 105
diff changeset
442 for line in comment_header.splitlines():
317
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 311
diff changeset
443 lines += wraptext(line, width=width,
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 311
diff changeset
444 subsequent_indent='# ')
106
2a00e352c986 Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents: 105
diff changeset
445 comment_header = u'\n'.join(lines) + u'\n'
2a00e352c986 Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
cmlenz
parents: 105
diff changeset
446 _write(comment_header)
104
57d2f21a1fcc Project name and version, and the charset are available via the `Catalog` object, and do not need to be passed to `write_pot()`.
cmlenz
parents: 99
diff changeset
447
229
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 228
diff changeset
448 for comment in message.user_comments:
183
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
449 _write_comment(comment)
229
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 228
diff changeset
450 for comment in message.auto_comments:
183
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
451 _write_comment(comment, prefix='.')
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
452
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
453 if not no_location:
136
9e3d2b227ec3 More fixes for Windows compatibility:
cmlenz
parents: 122
diff changeset
454 locs = u' '.join([u'%s:%d' % (filename.replace(os.sep, '/'), lineno)
9e3d2b227ec3 More fixes for Windows compatibility:
cmlenz
parents: 122
diff changeset
455 for filename, lineno in message.locations])
183
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
456 _write_comment(locs, prefix=':')
58
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 57
diff changeset
457 if message.flags:
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 57
diff changeset
458 _write('#%s\n' % ', '.join([''] + list(message.flags)))
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
459
205
aefe4ac123a2 Minor changes to how previous msgids are processed.
cmlenz
parents: 202
diff changeset
460 if message.previous_id and include_previous:
311
7e460ba1aabe Fix for unicode problem when the previous message id is included as a comment in PO serialization. Closes #78.
cmlenz
parents: 250
diff changeset
461 _write_comment('msgid %s' % _normalize(message.previous_id[0]),
205
aefe4ac123a2 Minor changes to how previous msgids are processed.
cmlenz
parents: 202
diff changeset
462 prefix='|')
aefe4ac123a2 Minor changes to how previous msgids are processed.
cmlenz
parents: 202
diff changeset
463 if len(message.previous_id) > 1:
311
7e460ba1aabe Fix for unicode problem when the previous message id is included as a comment in PO serialization. Closes #78.
cmlenz
parents: 250
diff changeset
464 _write_comment('msgid_plural %s' % _normalize(
205
aefe4ac123a2 Minor changes to how previous msgids are processed.
cmlenz
parents: 202
diff changeset
465 message.previous_id[1]
aefe4ac123a2 Minor changes to how previous msgids are processed.
cmlenz
parents: 202
diff changeset
466 ), prefix='|')
202
d3c272492053 Added `--no-fuzzy-matching` to the frontends and also `--previous` which adds the old msgid's as comments. The latest closes #31.
palgarvio
parents: 201
diff changeset
467
183
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
468 _write_message(message)
26
93eaa2f4a0a2 Reimplement line wrapping for PO writing (as the `textwrap` module is too destructive with white space) and move it to the `normalize` function (which was already doing some handling of line breaks).
cmlenz
parents: 25
diff changeset
469 _write('\n')
183
e927dffc9ab4 The frontends now provide ways to update existing translations catalogs from a template. Closes #22.
cmlenz
parents: 180
diff changeset
470
193
b5e58a22ebd2 Add an option to the frontend commands for catalog updating that removes completely any obsolete messages, instead of putting them comments.
cmlenz
parents: 192
diff changeset
471 if not ignore_obsolete:
b5e58a22ebd2 Add an option to the frontend commands for catalog updating that removes completely any obsolete messages, instead of putting them comments.
cmlenz
parents: 192
diff changeset
472 for message in catalog.obsolete.values():
229
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 228
diff changeset
473 for comment in message.user_comments:
193
b5e58a22ebd2 Add an option to the frontend commands for catalog updating that removes completely any obsolete messages, instead of putting them comments.
cmlenz
parents: 192
diff changeset
474 _write_comment(comment)
b5e58a22ebd2 Add an option to the frontend commands for catalog updating that removes completely any obsolete messages, instead of putting them comments.
cmlenz
parents: 192
diff changeset
475 _write_message(message, prefix='#~ ')
b5e58a22ebd2 Add an option to the frontend commands for catalog updating that removes completely any obsolete messages, instead of putting them comments.
cmlenz
parents: 192
diff changeset
476 _write('\n')
Copyright (C) 2012-2017 Edgewall Software