~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
274
274
        s = s[:-1]
275
275
        return s
276
276
 
277
 
    def get_help_text(self, additional_see_also=None):
 
277
    def get_help_text(self, additional_see_also=None, plain=True):
278
278
        """Return a text string with help for this command.
279
279
        
280
280
        :param additional_see_also: Additional help topics to be
281
281
            cross-referenced.
 
282
        :param plain: if False, raw help (reStructuredText) is
 
283
            returned instead of plain text.
282
284
        """
283
285
        doc = self.help()
284
286
        if doc is None:
285
287
            raise NotImplementedError("sorry, no detailed help yet for %r" % self.name())
286
288
 
 
289
        # Extract the summary (purpose) and sections out from the text
 
290
        purpose,sections = self._get_help_parts(doc)
 
291
 
 
292
        # If a custom usage section was provided, use it
 
293
        if sections.has_key('Usage'):
 
294
            usage = sections.pop('Usage')
 
295
        else:
 
296
            usage = self._usage()
 
297
 
 
298
        # The header is the purpose and usage
287
299
        result = ""
288
 
        result += 'usage: %s\n' % self._usage()
289
 
 
 
300
        result += ':Purpose: %s\n' % purpose
 
301
        if usage.find('\n') >= 0:
 
302
            result += ':Usage:\n%s\n' % usage
 
303
        else:
 
304
            result += ':Usage:   %s\n' % usage
 
305
        result += '\n'
 
306
 
 
307
        # Add the options
 
308
        options = option.get_optparser(self.options()).format_option_help()
 
309
        if options.startswith('Options:'):
 
310
            result += ':' + options
 
311
        elif options.startswith('options:'):
 
312
            # Python 2.4 version of optparse
 
313
            result += ':Options:' + options[len('options:'):]
 
314
        else:
 
315
            result += options
 
316
        result += '\n'
 
317
 
 
318
        # Add the description, indenting it 2 spaces
 
319
        # to match the indentation of the options
 
320
        if sections.has_key(None):
 
321
            text = sections.pop(None)
 
322
            text = '\n  '.join(text.splitlines())
 
323
            result += ':%s:\n  %s\n\n' % ('Description',text)
 
324
 
 
325
        # Add the custom sections (e.g. Examples). Note that there's no need
 
326
        # to indent these as they must be indented already in the source.
 
327
        if sections:
 
328
            labels = sorted(sections.keys())
 
329
            for label in labels:
 
330
                result += ':%s:\n%s\n\n' % (label,sections[label])
 
331
 
 
332
        # Add the aliases, source (plug-in) and see also links, if any
290
333
        if self.aliases:
291
 
            result += 'aliases: '
 
334
            result += ':Aliases:  '
292
335
            result += ', '.join(self.aliases) + '\n'
293
 
 
294
 
        result += '\n'
295
 
 
296
336
        plugin_name = self.plugin_name()
297
337
        if plugin_name is not None:
298
 
            result += '(From plugin "%s")' % plugin_name
299
 
            result += '\n\n'
300
 
 
301
 
        result += doc
302
 
        if result[-1] != '\n':
303
 
            result += '\n'
304
 
        result += '\n'
305
 
        result += option.get_optparser(self.options()).format_option_help()
 
338
            result += ':From:     plugin "%s"\n' % plugin_name
306
339
        see_also = self.get_see_also(additional_see_also)
307
340
        if see_also:
308
 
            result += '\nSee also: '
309
 
            result += ', '.join(see_also)
310
 
            result += '\n'
 
341
            result += ':See also: '
 
342
            result += ', '.join(see_also) + '\n'
 
343
 
 
344
        # If this will be rendered as plan text, convert it
 
345
        if plain:
 
346
            import bzrlib.help_topics
 
347
            result = bzrlib.help_topics.help_as_plain_text(result)
311
348
        return result
312
349
 
 
350
    @staticmethod
 
351
    def _get_help_parts(text):
 
352
        """Split help text into a summary and named sections.
 
353
 
 
354
        :return: (summary,sections) where summary is the top line and
 
355
            sections is a dictionary of the rest indexed by section name.
 
356
            A section starts with a heading line of the form ":xxx:".
 
357
            Indented text on following lines is the section value.
 
358
            All text found outside a named section is assigned to the
 
359
            default section which is given the key of None.
 
360
        """
 
361
        def save_section(sections, label, section):
 
362
            if len(section) > 0:
 
363
                if sections.has_key(label):
 
364
                    sections[label] += '\n' + section
 
365
                else:
 
366
                    sections[label] = section
 
367
            
 
368
        lines = text.rstrip().splitlines()
 
369
        summary = lines.pop(0)
 
370
        sections = {}
 
371
        label,section = None,''
 
372
        for line in lines:
 
373
            if line.startswith(':') and line.endswith(':') and len(line) > 2:
 
374
                save_section(sections, label, section)
 
375
                label,section = line[1:-1],''
 
376
            elif label != None and len(line) > 1 and not line[0].isspace():
 
377
                save_section(sections, label, section)
 
378
                label,section = None,line
 
379
            else:
 
380
                if len(section) > 0:
 
381
                    section += '\n' + line
 
382
                else:
 
383
                    section = line
 
384
        save_section(sections, label, section)
 
385
        return summary, sections
 
386
 
313
387
    def get_help_topic(self):
314
388
        """Return the commands help topic - its name."""
315
389
        return self.name()