annotate babel/messages/pofile.py @ 104:22f222e23b86

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.
author cmlenz
date Wed, 13 Jun 2007 23:02:24 +0000
parents 7cdf89eb9007
children f744dd56573d
rev   line source
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
2 #
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
3 # Copyright (C) 2007 Edgewall Software
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
4 # All rights reserved.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
5 #
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
8 # are also available at http://babel.edgewall.org/wiki/License.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
9 #
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://babel.edgewall.org/log/.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
13
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
14 """Reading and writing of files in the ``gettext`` PO (portable object)
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
15 format.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
16
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
17 :see: `The Format of PO Files
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
18 <http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files>`_
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
19 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
20
5
50ad95bee876 * The creation-date header in generated PO files now includes the timezone offset.
cmlenz
parents: 1
diff changeset
21 from datetime import date, datetime
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
22 import re
6
1801bc2b60ca 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
23 try:
1801bc2b60ca 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
24 set
1801bc2b60ca 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
25 except NameError:
1801bc2b60ca 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
26 from sets import Set as set
103
7cdf89eb9007 Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents: 102
diff changeset
27 from textwrap import wrap
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
28
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
29 from babel import __version__ as VERSION
56
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
30 from babel.messages.catalog import Catalog
97
a02952b73cf1 Renamed `LOCAL` to `LOCALTZ`.
cmlenz
parents: 96
diff changeset
31 from babel.util import LOCALTZ
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
32
104
22f222e23b86 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
33 __all__ = ['escape', 'normalize', 'read_po', 'write_po']
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
34
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
35 def read_po(fileobj):
6
1801bc2b60ca 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
36 """Read messages from a ``gettext`` PO (portable object) file from the given
64
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
37 file-like object and return a `Catalog`.
6
1801bc2b60ca 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
38
1801bc2b60ca 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
39 >>> from StringIO import StringIO
104
22f222e23b86 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
40 >>> buf = StringIO('''# Translations template for PROJECT.
22f222e23b86 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
41 ... # Copyright (C) YEAR COPYRIGHT HOLDER
22f222e23b86 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
42 ... # This file is distributed under the same license as the PROJECT project.
22f222e23b86 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
43 ... # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
22f222e23b86 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
44 ... #
22f222e23b86 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
45 ...
6
1801bc2b60ca 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
46 ... #: main.py:1
1801bc2b60ca 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
47 ... #, fuzzy, python-format
1801bc2b60ca 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
48 ... msgid "foo %(name)s"
1801bc2b60ca 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
49 ... msgstr ""
21
ddfac856c34f 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
50 ...
94
b176f325d127 Updated `read_po` to add user comments besides just auto comments.
palgarvio
parents: 84
diff changeset
51 ... # A user comment
b176f325d127 Updated `read_po` to add user comments besides just auto comments.
palgarvio
parents: 84
diff changeset
52 ... #. An auto comment
6
1801bc2b60ca 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
53 ... #: main.py:3
1801bc2b60ca 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
54 ... msgid "bar"
1801bc2b60ca 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
55 ... msgid_plural "baz"
1801bc2b60ca 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
56 ... msgstr[0] ""
1801bc2b60ca 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
57 ... msgstr[1] ""
1801bc2b60ca 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
58 ... ''')
64
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
59 >>> catalog = read_po(buf)
104
22f222e23b86 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
60 >>> catalog.revision_date = datetime(2007, 04, 01)
22f222e23b86 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
61
22f222e23b86 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
62 >>> print catalog.header_comment
22f222e23b86 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
63 # Translations template for PROJECT.
22f222e23b86 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
64 # Copyright (C) 2007 ORGANIZATION
22f222e23b86 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
65 # This file is distributed under the same license as the PROJECT project.
22f222e23b86 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
66 # FIRST AUTHOR <EMAIL@ADDRESS>, 2007.
22f222e23b86 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
67
64
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
68 >>> for message in catalog:
67
5496b9127a07 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 64
diff changeset
69 ... if message.id:
5496b9127a07 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 64
diff changeset
70 ... print (message.id, message.string)
94
b176f325d127 Updated `read_po` to add user comments besides just auto comments.
palgarvio
parents: 84
diff changeset
71 ... print ' ', (message.locations, message.flags, message.comments)
64
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
72 ('foo %(name)s', '')
94
b176f325d127 Updated `read_po` to add user comments besides just auto comments.
palgarvio
parents: 84
diff changeset
73 ([('main.py', 1)], set(['fuzzy', 'python-format']), [])
6
1801bc2b60ca 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
74 (('bar', 'baz'), ('', ''))
94
b176f325d127 Updated `read_po` to add user comments besides just auto comments.
palgarvio
parents: 84
diff changeset
75 ([('main.py', 3)], set([]), ['A user comment', 'An auto comment'])
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
76
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
77 :param fileobj: the file-like object to read the PO file from
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
78 :return: an iterator over ``(message, translation, location)`` tuples
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
79 :rtype: ``iterator``
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
80 """
64
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
81 catalog = Catalog()
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
82
6
1801bc2b60ca 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
83 messages = []
1801bc2b60ca 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
84 translations = []
1801bc2b60ca 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
85 locations = []
1801bc2b60ca 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
86 flags = []
84
4ff9cc26c11b Some cosmetic changes for the new translator comments support.
cmlenz
parents: 80
diff changeset
87 comments = []
6
1801bc2b60ca 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 in_msgid = in_msgstr = False
104
22f222e23b86 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
89 in_header = True
22f222e23b86 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
90 header_lines = []
6
1801bc2b60ca 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
64
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
92 def _add_message():
6
1801bc2b60ca 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 translations.sort()
64
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
94 if len(messages) > 1:
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
95 msgid = tuple(messages)
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
96 else:
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
97 msgid = messages[0]
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
98 if len(translations) > 1:
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
99 string = tuple([t[1] for t in translations])
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
100 else:
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
101 string = translations[0][1]
84
4ff9cc26c11b Some cosmetic changes for the new translator comments support.
cmlenz
parents: 80
diff changeset
102 catalog.add(msgid, string, list(locations), set(flags), list(comments))
4ff9cc26c11b Some cosmetic changes for the new translator comments support.
cmlenz
parents: 80
diff changeset
103 del messages[:]; del translations[:]; del locations[:];
4ff9cc26c11b Some cosmetic changes for the new translator comments support.
cmlenz
parents: 80
diff changeset
104 del flags[:]; del comments[:]
6
1801bc2b60ca 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
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
106 for line in fileobj.readlines():
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
107 line = line.strip()
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
108 if line.startswith('#'):
104
22f222e23b86 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
109 if in_header and line[1:].startswith(' '):
22f222e23b86 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
110 header_lines.append(line)
22f222e23b86 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
111 else:
22f222e23b86 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
112 in_header = in_msgid = in_msgstr = False
22f222e23b86 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
113 if messages:
22f222e23b86 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
114 _add_message()
22f222e23b86 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
115 if line[1:].startswith(':'):
22f222e23b86 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
116 for location in line[2:].lstrip().split():
22f222e23b86 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
117 filename, lineno = location.split(':', 1)
22f222e23b86 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
118 locations.append((filename, int(lineno)))
22f222e23b86 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
119 elif line[1:].startswith(','):
22f222e23b86 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
120 for flag in line[2:].lstrip().split(','):
22f222e23b86 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
121 flags.append(flag.strip())
22f222e23b86 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
122 elif line[1:].startswith('.'):
22f222e23b86 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
123 # These are called auto-comments
22f222e23b86 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
124 comment = line[2:].strip()
22f222e23b86 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
125 if comment:
22f222e23b86 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
126 # Just check that we're not adding empty comments
22f222e23b86 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
127 comments.append(comment)
22f222e23b86 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
128 elif line[1:].startswith(' '):
22f222e23b86 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
129 # These are called user comments
22f222e23b86 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
130 comment = line[1:].strip()
22f222e23b86 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
131 if comment:
22f222e23b86 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
132 # Just check that we're not adding empty comments
22f222e23b86 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
133 comments.append(comment)
22f222e23b86 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
134 else:
22f222e23b86 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
135 in_header = False
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
136 if line.startswith('msgid_plural'):
6
1801bc2b60ca 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 in_msgid = True
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
138 msg = line[12:].lstrip()
6
1801bc2b60ca 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
139 messages.append(msg[1:-1])
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
140 elif line.startswith('msgid'):
6
1801bc2b60ca 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
141 in_msgid = True
1801bc2b60ca 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
142 if messages:
64
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
143 _add_message()
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
144 msg = line[5:].lstrip()
6
1801bc2b60ca 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 messages.append(msg[1:-1])
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
146 elif line.startswith('msgstr'):
6
1801bc2b60ca 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 in_msgid = False
1801bc2b60ca 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
148 in_msgstr = True
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
149 msg = line[6:].lstrip()
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
150 if msg.startswith('['):
6
1801bc2b60ca 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
151 idx, msg = msg[1:].split(']')
1801bc2b60ca 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
152 translations.append([int(idx), msg.lstrip()[1:-1]])
1801bc2b60ca 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
153 else:
1801bc2b60ca 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
154 translations.append([0, msg[1:-1]])
1801bc2b60ca 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
155 elif line.startswith('"'):
1801bc2b60ca 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
156 if in_msgid:
1801bc2b60ca 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
157 messages[-1] += line.rstrip()[1:-1]
1801bc2b60ca 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
158 elif in_msgstr:
1801bc2b60ca 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
159 translations[-1][1] += line.rstrip()[1:-1]
1801bc2b60ca 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
160
104
22f222e23b86 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
161 catalog.header_comment = '\n'.join(header_lines)
6
1801bc2b60ca 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
162 if messages:
64
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
163 _add_message()
0406c51c5463 `read_po` now returns a `Catalog`.
cmlenz
parents: 56
diff changeset
164 return catalog
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
165
24
4fad20ab7cca 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
166 WORD_SEP = re.compile('('
4fad20ab7cca 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
167 r'\s+|' # any whitespace
4fad20ab7cca 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
168 r'[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|' # hyphenated words
4fad20ab7cca 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
169 r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w)' # em-dash
4fad20ab7cca 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
170 ')')
4fad20ab7cca 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
171
4fad20ab7cca 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
172 def escape(string):
4fad20ab7cca 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
173 r"""Escape the given string so that it can be included in double-quoted
4fad20ab7cca 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
174 strings in ``PO`` files.
4fad20ab7cca 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
175
4fad20ab7cca 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
176 >>> escape('''Say:
4fad20ab7cca 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
177 ... "hello, world!"
4fad20ab7cca 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
178 ... ''')
4fad20ab7cca 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
179 '"Say:\\n \\"hello, world!\\"\\n"'
4fad20ab7cca 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
180
4fad20ab7cca 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
181 :param string: the string to escape
4fad20ab7cca 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
182 :return: the escaped string
4fad20ab7cca 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
183 :rtype: `str` or `unicode`
4fad20ab7cca 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
184 """
4fad20ab7cca 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
185 return '"%s"' % string.replace('\\', '\\\\') \
4fad20ab7cca 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
186 .replace('\t', '\\t') \
4fad20ab7cca 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
187 .replace('\r', '\\r') \
4fad20ab7cca 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
188 .replace('\n', '\\n') \
4fad20ab7cca 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
189 .replace('\"', '\\"')
4fad20ab7cca 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
190
4fad20ab7cca 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
191 def normalize(string, width=76):
4fad20ab7cca 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
192 r"""This converts a string into a format that is appropriate for .po files.
4fad20ab7cca 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
193
4fad20ab7cca 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
194 >>> print normalize('''Say:
4fad20ab7cca 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
195 ... "hello, world!"
4fad20ab7cca 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
196 ... ''', width=None)
4fad20ab7cca 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
197 ""
4fad20ab7cca 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
198 "Say:\n"
4fad20ab7cca 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
199 " \"hello, world!\"\n"
4fad20ab7cca 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
200
4fad20ab7cca 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
201 >>> print normalize('''Say:
4fad20ab7cca 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
202 ... "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
4fad20ab7cca 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
203 ... ''', width=32)
4fad20ab7cca 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
204 ""
4fad20ab7cca 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
205 "Say:\n"
4fad20ab7cca 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
206 " \"Lorem ipsum dolor sit "
4fad20ab7cca 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
207 "amet, consectetur adipisicing"
4fad20ab7cca 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
208 " elit, \"\n"
4fad20ab7cca 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
209
4fad20ab7cca 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
210 :param string: the string to normalize
4fad20ab7cca 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
211 :param width: the maximum line width; use `None`, 0, or a negative number
4fad20ab7cca 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
212 to completely disable line wrapping
4fad20ab7cca 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
213 :return: the normalized string
4fad20ab7cca 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
214 :rtype: `unicode`
4fad20ab7cca 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
215 """
4fad20ab7cca 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
216 if width and width > 0:
4fad20ab7cca 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
217 lines = []
4fad20ab7cca 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
218 for idx, line in enumerate(string.splitlines(True)):
4fad20ab7cca 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
219 if len(escape(line)) > width:
4fad20ab7cca 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
220 chunks = WORD_SEP.split(line)
4fad20ab7cca 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
221 chunks.reverse()
4fad20ab7cca 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
222 while chunks:
4fad20ab7cca 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
223 buf = []
4fad20ab7cca 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
224 size = 2
4fad20ab7cca 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
225 while chunks:
4fad20ab7cca 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
226 l = len(escape(chunks[-1])) - 2
4fad20ab7cca 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
227 if size + l < width:
4fad20ab7cca 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
228 buf.append(chunks.pop())
4fad20ab7cca 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
229 size += l
4fad20ab7cca 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
230 else:
4fad20ab7cca 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
231 if not buf:
4fad20ab7cca 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
232 # handle long chunks by putting them on a
4fad20ab7cca 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
233 # separate line
4fad20ab7cca 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
234 buf.append(chunks.pop())
4fad20ab7cca 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
235 break
4fad20ab7cca 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
236 lines.append(u''.join(buf))
4fad20ab7cca 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
237 else:
4fad20ab7cca 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
238 lines.append(line)
4fad20ab7cca 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
239 else:
4fad20ab7cca 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
240 lines = string.splitlines(True)
4fad20ab7cca 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
241
67
5496b9127a07 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 64
diff changeset
242 if len(lines) <= 1:
24
4fad20ab7cca 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
243 return escape(string)
4fad20ab7cca 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
244
4fad20ab7cca 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
245 # Remove empty trailing line
67
5496b9127a07 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 64
diff changeset
246 if lines and not lines[-1]:
24
4fad20ab7cca 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
247 del lines[-1]
4fad20ab7cca 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
248 lines[-1] += '\n'
4fad20ab7cca 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
249 return u'""\n' + u'\n'.join([escape(l) for l in lines])
4fad20ab7cca 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
250
104
22f222e23b86 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
251 def write_po(fileobj, catalog, width=76, no_location=False, omit_header=False,
22f222e23b86 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
252 sort_output=False, sort_by_file=False):
56
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
253 r"""Write a ``gettext`` PO (portable object) template file for a given
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
254 message catalog to the provided file-like object.
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
255
56
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
256 >>> catalog = Catalog()
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
257 >>> catalog.add(u'foo %(name)s', locations=[('main.py', 1)],
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
258 ... flags=('fuzzy',))
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
259 >>> catalog.add((u'bar', u'baz'), locations=[('main.py', 3)])
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
260 >>> from StringIO import StringIO
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
261 >>> buf = StringIO()
104
22f222e23b86 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
262 >>> write_po(buf, catalog, omit_header=True)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
263 >>> print buf.getvalue()
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
264 #: main.py:1
6
1801bc2b60ca 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
265 #, fuzzy, python-format
1801bc2b60ca 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
266 msgid "foo %(name)s"
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
267 msgstr ""
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
268 <BLANKLINE>
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
269 #: main.py:3
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
270 msgid "bar"
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
271 msgid_plural "baz"
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
272 msgstr[0] ""
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
273 msgstr[1] ""
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
274 <BLANKLINE>
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
275 <BLANKLINE>
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
276
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
277 :param fileobj: the file-like object to write to
67
5496b9127a07 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 64
diff changeset
278 :param catalog: the `Catalog` instance
24
4fad20ab7cca 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 :param width: the maximum line width for the generated output; use `None`,
4fad20ab7cca 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 0, or a negative number to completely disable line wrapping
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
281 :param no_location: do not emit a location comment for every message
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
282 :param omit_header: do not include the ``msgid ""`` entry at the top of the
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
283 output
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
284 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
285 def _normalize(key):
102
eb0d9591d555 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
286 return normalize(key, width=width).encode(catalog.charset,
eb0d9591d555 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
287 'backslashreplace')
24
4fad20ab7cca 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
4fad20ab7cca 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 def _write(text):
4fad20ab7cca 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 if isinstance(text, unicode):
102
eb0d9591d555 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
291 text = text.encode(catalog.charset)
24
4fad20ab7cca 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 fileobj.write(text)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
293
104
22f222e23b86 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
294 messages = list(catalog)
71
ea4cb904df8f Implemented message sorting, see #7.
palgarvio
parents: 68
diff changeset
295 if sort_output:
ea4cb904df8f Implemented message sorting, see #7.
palgarvio
parents: 68
diff changeset
296 messages.sort(lambda x,y: cmp(x.id, y.id))
ea4cb904df8f Implemented message sorting, see #7.
palgarvio
parents: 68
diff changeset
297 elif sort_by_file:
ea4cb904df8f Implemented message sorting, see #7.
palgarvio
parents: 68
diff changeset
298 messages.sort(lambda x,y: cmp(x.locations, y.locations))
68
7e64668126d9 Add back POT header broken in previous check-in.
cmlenz
parents: 67
diff changeset
299
71
ea4cb904df8f Implemented message sorting, see #7.
palgarvio
parents: 68
diff changeset
300 for message in messages:
67
5496b9127a07 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 64
diff changeset
301 if not message.id: # This is the header "message"
5496b9127a07 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 64
diff changeset
302 if omit_header:
5496b9127a07 Enhance catalog to also manage the MIME headers.
cmlenz
parents: 64
diff changeset
303 continue
104
22f222e23b86 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
304 comment_header = catalog.header_comment
103
7cdf89eb9007 Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents: 102
diff changeset
305 if width and width > 0:
7cdf89eb9007 Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents: 102
diff changeset
306 lines = []
104
22f222e23b86 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
307 for line in comment_header.splitlines():
103
7cdf89eb9007 Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents: 102
diff changeset
308 lines += wrap(line, width=width, subsequent_indent='# ',
7cdf89eb9007 Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents: 102
diff changeset
309 break_long_words=False)
104
22f222e23b86 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
310 comment_header = u'\n'.join(lines) + u'\n'
22f222e23b86 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
311 _write(comment_header)
102
eb0d9591d555 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
312
80
9c84b9fa5d30 Added support for translator comments at the API and frontends levels.(See #12, item 1). Updated docs and tests accordingly.
palgarvio
parents: 79
diff changeset
313 if message.comments:
9c84b9fa5d30 Added support for translator comments at the API and frontends levels.(See #12, item 1). Updated docs and tests accordingly.
palgarvio
parents: 79
diff changeset
314 for comment in message.comments:
103
7cdf89eb9007 Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents: 102
diff changeset
315 for line in wrap(comment, width, break_long_words=False):
80
9c84b9fa5d30 Added support for translator comments at the API and frontends levels.(See #12, item 1). Updated docs and tests accordingly.
palgarvio
parents: 79
diff changeset
316 _write('#. %s\n' % line.strip())
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
317
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
318 if not no_location:
56
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
319 locs = u' '.join([u'%s:%d' % item for item in message.locations])
24
4fad20ab7cca 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 if width and width > 0:
103
7cdf89eb9007 Implement wrapping of header comments in PO(T) output. Related to #14.
cmlenz
parents: 102
diff changeset
321 locs = wrap(locs, width, break_long_words=False)
24
4fad20ab7cca 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 for line in locs:
4fad20ab7cca 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 _write('#: %s\n' % line.strip())
56
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
324 if message.flags:
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
325 _write('#%s\n' % ', '.join([''] + list(message.flags)))
24
4fad20ab7cca 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
56
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
327 if isinstance(message.id, (list, tuple)):
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
328 _write('msgid %s\n' % _normalize(message.id[0]))
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
329 _write('msgid_plural %s\n' % _normalize(message.id[1]))
68
7e64668126d9 Add back POT header broken in previous check-in.
cmlenz
parents: 67
diff changeset
330 for i, string in enumerate(message.string):
7e64668126d9 Add back POT header broken in previous check-in.
cmlenz
parents: 67
diff changeset
331 _write('msgstr[%d] %s\n' % (i, _normalize(message.string[i])))
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
332 else:
56
27fba894d3ca Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 55
diff changeset
333 _write('msgid %s\n' % _normalize(message.id))
68
7e64668126d9 Add back POT header broken in previous check-in.
cmlenz
parents: 67
diff changeset
334 _write('msgstr %s\n' % _normalize(message.string or ''))
24
4fad20ab7cca 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 _write('\n')
Copyright (C) 2012-2017 Edgewall Software