Python Textwrap - форсирование «жестких» разрывов - PullRequest
1 голос
/ 19 мая 2010

Я пытаюсь использовать textwrap для форматирования файла импорта, который довольно специфичен в том, как он отформатирован. По сути, это выглядит следующим образом (длина строки сокращена для простоты):

abcdef <- Ok line
abcdef 
 ghijk <- Note leading space to indicate wrapped line
 lm

Теперь у меня есть код для работы следующим образом:

wrapper = TextWrapper(width=80, subsequent_indent=' ', break_long_words=True, break_on_hyphens=False)
for l in lines:
  wrapline=wrapper.wrap(l)

Это работает почти идеально, однако код переноса текста не делает резких разрывов при отметке в 80 символов, он пытается быть умным и разбивать на пробелы (примерно 20 символов в).

Я обошёл это, заменив все пробелы в списке строк уникальным символом (#), обернув их, а затем удалив символ, но наверняка должен быть более чистый путь?

N.B. Любые возможные ответы должны работать на Python 2.4 - извините!

Ответы [ 2 ]

1 голос
/ 11 июля 2010

Генераторная версия может быть лучшим решением для вас, поскольку ей не нужно загружать всю строку в память сразу:

def hard_wrap(input, width, indent=' '):
   for line in input:
      indent_width = width - len(indent)
      yield line[:width]
      line = line[width:]
      while line:
         yield '\n' + indent + line[:indent_width]
         line = line[indent_width:]

Используйте это так:

from StringIO import StringIO # Makes strings look like files

s = """abcdefg
abcdefghijklmnopqrstuvwxyz"""

for line in hard_wrap(StringIO(s), 12):
   print line,

Какие отпечатки:

abcdefg
abcdefghijkl 
 mnopqrstuvw 
 xyz
1 голос
/ 19 мая 2010

Похоже, вы отключили большую часть функциональности TextWrapper, а затем пытаетесь добавить немного своих собственных. Я думаю, вам лучше написать свою собственную функцию или класс. Если я вас правильно понял, вы просто ищете строки длиннее 80 символов, разбиваете их на отметке 80 символов и делаете отступ в одну строку.

Например, это:

s = """\
This line is fine.
This line is very long and should wrap, It'll end up on a few lines.
A short line.
"""

def hard_wrap(s, n, indent):
    wrapped = ""
    n_next = n - len(indent)
    for l in s.split('\n'):
        first, rest = l[:n], l[n:]
        wrapped += first + "\n"
        while rest:
            next, rest = rest[:n_next], rest[n_next:]
            wrapped += indent + next + "\n"
    return wrapped

print hard_wrap(s, 20, " ")

производит:

This line is fine.
This line is very lo
 ng and should wrap,
  It'll end up on a
 few lines.
A short line.
...