/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/export_pot.py

(gz) Add _PotExporter and other refactorings to export_pot module (Martin
 Packman)

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
# with Python under the Python License, which is GPL compatible.
19
19
 
20
20
"""Extract docstrings from Bazaar commands.
 
21
 
 
22
This module only handles bzrlib objects that use strings not directly wrapped
 
23
by a gettext() call. To generate a complete translation template file, this
 
24
output needs to be combined with that of xgettext or a similar command for
 
25
extracting those strings, as is done in the bzr Makefile. Sorting the output
 
26
is also left to that stage of the process.
21
27
"""
22
28
 
23
29
import inspect
62
68
    return s
63
69
 
64
70
 
65
 
_FOUND_MSGID = None # set by entry function.
66
 
 
67
 
def _poentry(outf, path, lineno, s, comment=None):
68
 
    if s in _FOUND_MSGID:
69
 
        return
70
 
    _FOUND_MSGID.add(s)
71
 
    if comment is None:
72
 
        comment = ''
73
 
    else:
74
 
        comment = "# %s\n" % comment
75
 
    mutter("Exporting msg %r at line %d in %r", s[:20], lineno, path)
76
 
    print >>outf, ('#: %s:%d\n' % (path, lineno) +
77
 
           comment+
78
 
           'msgid %s\n' % _normalize(s) +
79
 
           'msgstr ""\n')
80
 
 
81
 
def _poentry_per_paragraph(outf, path, lineno, msgid, filter=lambda x: False):
82
 
    # TODO: How to split long help?
83
 
    paragraphs = msgid.split('\n\n')
84
 
    for p in paragraphs:
85
 
        if filter(p):
86
 
            continue
87
 
        _poentry(outf, path, lineno, p)
88
 
        lineno += p.count('\n') + 2
 
71
class _PotExporter(object):
 
72
    """Write message details to output stream in .pot file format"""
 
73
 
 
74
    def __init__(self, outf):
 
75
        self.outf = outf
 
76
        self._msgids = set()
 
77
 
 
78
    def poentry(self, path, lineno, s, comment=None):
 
79
        if s in self._msgids:
 
80
            return
 
81
        self._msgids.add(s)
 
82
        if comment is None:
 
83
            comment = ''
 
84
        else:
 
85
            comment = "# %s\n" % comment
 
86
        mutter("Exporting msg %r at line %d in %r", s[:20], lineno, path)
 
87
        self.outf.write(
 
88
            "#: {path}:{lineno}\n"
 
89
            "{comment}"
 
90
            "msgid {msg}\n"
 
91
            "msgstr \"\"\n"
 
92
            "\n".format(
 
93
                path=path, lineno=lineno, comment=comment, msg=_normalize(s)))
 
94
 
 
95
    def poentry_per_paragraph(self, path, lineno, msgid, include=None):
 
96
        # TODO: How to split long help?
 
97
        paragraphs = msgid.split('\n\n')
 
98
        if include is not None:
 
99
            paragraphs = filter(include, paragraphs)
 
100
        for p in paragraphs:
 
101
            self.poentry(path, lineno, p)
 
102
            lineno += p.count('\n') + 2
 
103
 
89
104
 
90
105
_LAST_CACHE = _LAST_CACHED_SRC = None
91
106
 
106
121
    _LAST_CACHE = offsets.copy()
107
122
    return offsets
108
123
 
109
 
def _standard_options(outf):
 
124
def _standard_options(exporter):
110
125
    from bzrlib.option import Option
111
126
    src = inspect.findsource(Option)[0]
112
127
    src = ''.join(src)
121
136
            lineno = offsets.get(opt.title, 9999)
122
137
            if lineno == 9999:
123
138
                note(gettext("%r is not found in bzrlib/option.py") % opt.title)
124
 
            _poentry(outf, path, lineno, opt.title,
 
139
            exporter.poentry(path, lineno, opt.title,
125
140
                     'title of %r option' % name)
126
141
        if getattr(opt, 'help', None):
127
142
            lineno = offsets.get(opt.help, 9999)
128
143
            if lineno == 9999:
129
144
                note(gettext("%r is not found in bzrlib/option.py") % opt.help)
130
 
            _poentry(outf, path, lineno, opt.help,
 
145
            exporter.poentry(path, lineno, opt.help,
131
146
                     'help of %r option' % name)
132
147
 
133
 
def _command_options(outf, path, cmd):
 
148
def _command_options(exporter, path, cmd):
134
149
    src, default_lineno = inspect.findsource(cmd.__class__)
135
150
    offsets = _offsets_of_literal(''.join(src))
136
151
    for opt in cmd.takes_options:
141
156
        name = opt.name
142
157
        if getattr(opt, 'title', None):
143
158
            lineno = offsets.get(opt.title, default_lineno)
144
 
            _poentry(outf, path, lineno, opt.title,
 
159
            exporter.poentry(path, lineno, opt.title,
145
160
                     'title of %r option of %r command' % (name, cmd.name()))
146
161
        if getattr(opt, 'help', None):
147
162
            lineno = offsets.get(opt.help, default_lineno)
148
 
            _poentry(outf, path, lineno, opt.help,
 
163
            exporter.poentry(path, lineno, opt.help,
149
164
                     'help of %r option of %r command' % (name, cmd.name()))
150
165
 
151
166
 
152
 
def _write_command_help(outf, cmd):
 
167
def _write_command_help(exporter, cmd):
153
168
    path = inspect.getfile(cmd.__class__)
154
169
    if path.endswith('.pyc'):
155
170
        path = path[:-1]
159
174
    lineno = offsets[cmd.__doc__]
160
175
    doc = inspect.getdoc(cmd)
161
176
 
162
 
    def filter(p):
 
177
    def exclude_usage(p):
163
178
        # ':Usage:' has special meaning in help topics.
164
179
        # This is usage example of command and should not be translated.
165
 
        if p.splitlines()[0] == ':Usage:':
 
180
        if p.splitlines()[0] != ':Usage:':
166
181
            return True
167
182
 
168
 
    _poentry_per_paragraph(outf, path, lineno, doc, filter)
169
 
    _command_options(outf, path, cmd)
170
 
 
171
 
 
172
 
def _command_helps(outf, plugin_name=None):
 
183
    exporter.poentry_per_paragraph(path, lineno, doc, exclude_usage)
 
184
    _command_options(exporter, path, cmd)
 
185
 
 
186
 
 
187
def _command_helps(exporter, plugin_name=None):
173
188
    """Extract docstrings from path.
174
189
 
175
190
    This respects the Bazaar cmdtable/table convention and will
186
201
            # only export builtins if we are not exporting plugin commands
187
202
            continue
188
203
        note(gettext("Exporting messages from builtin command: %s"), cmd_name)
189
 
        _write_command_help(outf, command)
 
204
        _write_command_help(exporter, command)
190
205
 
191
206
    plugin_path = plugin.get_core_plugin_path()
192
207
    core_plugins = glob(plugin_path + '/*/__init__.py')
206
221
            continue
207
222
        note(gettext("Exporting messages from plugin command: {0} in {1}").format(
208
223
             cmd_name, command.plugin_name() ))
209
 
        _write_command_help(outf, command)
210
 
 
211
 
 
212
 
def _error_messages(outf):
 
224
        _write_command_help(exporter, command)
 
225
 
 
226
 
 
227
def _error_messages(exporter):
213
228
    """Extract fmt string from bzrlib.errors."""
214
229
    path = errors.__file__
215
230
    if path.endswith('.pyc'):
230
245
        fmt = getattr(klass, "_fmt", None)
231
246
        if fmt:
232
247
            note(gettext("Exporting message from error: %s"), name)
233
 
            _poentry(outf, 'bzrlib/errors.py',
 
248
            exporter.poentry('bzrlib/errors.py',
234
249
                     offsets.get(fmt, 9999), fmt)
235
250
 
236
 
def _help_topics(outf):
 
251
def _help_topics(exporter):
237
252
    topic_registry = help_topics.topic_registry
238
253
    for key in topic_registry.keys():
239
254
        doc = topic_registry.get(key)
240
255
        if isinstance(doc, str):
241
 
            _poentry_per_paragraph(
242
 
                    outf,
 
256
            exporter.poentry_per_paragraph(
243
257
                    'dummy/help_topics/'+key+'/detail.txt',
244
258
                    1, doc)
245
259
        elif callable(doc): # help topics from files
246
 
            _poentry_per_paragraph(
247
 
                    outf,
 
260
            exporter.poentry_per_paragraph(
248
261
                    'en/help_topics/'+key+'.txt',
249
262
                    1, doc(key))
250
263
        summary = topic_registry.get_summary(key)
251
264
        if summary is not None:
252
 
            _poentry(outf, 'dummy/help_topics/'+key+'/summary.txt',
 
265
            exporter.poentry('dummy/help_topics/'+key+'/summary.txt',
253
266
                     1, summary)
254
267
 
255
268
def export_pot(outf, plugin=None):
256
 
    global _FOUND_MSGID
257
 
    _FOUND_MSGID = set()
 
269
    exporter = _PotExporter(outf)
258
270
    if plugin is None:
259
 
        _standard_options(outf)
260
 
        _command_helps(outf)
261
 
        _error_messages(outf)
262
 
        _help_topics(outf)
 
271
        _standard_options(exporter)
 
272
        _command_helps(exporter)
 
273
        _error_messages(exporter)
 
274
        _help_topics(exporter)
263
275
    else:
264
 
        _command_helps(outf, plugin)
 
276
        _command_helps(exporter, plugin)