~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/rio.py

  • Committer: John Arbash Meinel
  • Date: 2006-10-06 07:13:51 UTC
  • mto: This revision was merged to the branch mainline in revision 2071.
  • Revision ID: john@arbash-meinel.com-20061006071351-e3fdd47eed1c3e7e
lazy import revisionspec and errors for bzrlib.options

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Canonical Ltd
2
 
#
3
 
# This program is free software; you can redistribute it and/or modify
4
 
# it under the terms of the GNU General Public License as published by
5
 
# the Free Software Foundation; either version 2 of the License, or
6
 
# (at your option) any later version.
7
 
#
8
 
# This program is distributed in the hope that it will be useful,
9
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
# GNU General Public License for more details.
12
 
#
13
 
# You should have received a copy of the GNU General Public License
14
 
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
1
# Copyright (C) 2005 by Canonical Ltd
 
2
#
 
3
# Distributed under the GNU General Public Licence v2
16
4
 
17
5
# \subsection{\emph{rio} - simple text metaformat}
18
6
315
303
        return stanza
316
304
    else:     # didn't see any content
317
305
        return None    
318
 
 
319
 
 
320
 
def to_patch_lines(stanza, max_width=72):
321
 
    """Convert a stanza into RIO-Patch format lines.
322
 
 
323
 
    RIO-Patch is a RIO variant designed to be e-mailed as part of a patch.
324
 
    It resists common forms of damage such as newline conversion or the removal
325
 
    of trailing whitespace, yet is also reasonably easy to read.
326
 
 
327
 
    :param max_width: The maximum number of characters per physical line.
328
 
    :return: a list of lines
329
 
    """
330
 
    assert max_width > 6
331
 
    max_rio_width = max_width - 4
332
 
    lines = []
333
 
    for pline in stanza.to_lines():
334
 
        for line in pline.split('\n')[:-1]:
335
 
            line = re.sub('\\\\', '\\\\\\\\', line)
336
 
            while len(line) > 0:
337
 
                partline = line[:max_rio_width]
338
 
                line = line[max_rio_width:]
339
 
                if len(line) > 0 and line[0] != [' ']:
340
 
                    break_index = -1
341
 
                    break_index = partline.rfind(' ', -20)
342
 
                    if break_index < 3:
343
 
                        break_index = partline.rfind('-', -20)
344
 
                        break_index += 1
345
 
                    if break_index < 3:
346
 
                        break_index = partline.rfind('/', -20)
347
 
                    if break_index >= 3:
348
 
                        line = partline[break_index:] + line
349
 
                        partline = partline[:break_index]
350
 
                if len(line) > 0:
351
 
                    line = '  ' + line
352
 
                partline = re.sub('\r', '\\\\r', partline)
353
 
                blank_line = False
354
 
                if len(line) > 0:
355
 
                    partline += '\\'
356
 
                elif re.search(' $', partline):
357
 
                    partline += '\\'
358
 
                    blank_line = True
359
 
                lines.append('# ' + partline + '\n')
360
 
                if blank_line:
361
 
                    lines.append('#   \n')
362
 
    return lines
363
 
 
364
 
 
365
 
def _patch_stanza_iter(line_iter):
366
 
    map = {'\\\\': '\\',
367
 
           '\\r' : '\r',
368
 
           '\\\n': ''}
369
 
    def mapget(match):
370
 
        return map[match.group(0)]
371
 
 
372
 
    last_line = None
373
 
    for line in line_iter:
374
 
        if line.startswith('# '):
375
 
            line = line[2:]
376
 
        else:
377
 
            assert line.startswith('#')
378
 
            line = line[1:]
379
 
        if last_line is not None and len(line) > 2:
380
 
            line = line[2:]
381
 
        line = re.sub('\r', '', line)
382
 
        line = re.sub('\\\\(.|\n)', mapget, line)
383
 
        if last_line is None:
384
 
            last_line = line
385
 
        else:
386
 
            last_line += line
387
 
        if last_line[-1] == '\n':
388
 
            yield last_line
389
 
            last_line = None
390
 
    if last_line is not None:
391
 
        yield last_line
392
 
 
393
 
 
394
 
def read_patch_stanza(line_iter):
395
 
    """Convert an iterable of RIO-Patch format lines into a Stanza.
396
 
 
397
 
    RIO-Patch is a RIO variant designed to be e-mailed as part of a patch.
398
 
    It resists common forms of damage such as newline conversion or the removal
399
 
    of trailing whitespace, yet is also reasonably easy to read.
400
 
 
401
 
    :return: a Stanza
402
 
    """
403
 
    return read_stanza(_patch_stanza_iter(line_iter))