annotate babel/messages/pofile.py @ 586:46410022772a trunk

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