ТранскрибаторТранскрибатор
Практическая инструкция

Python textwrap: как переверстать абзацы расшифровки без склейки говорящих

Новая ширина строк TXT через textwrap.fill с сохранением границ абзацев. Когда метод подходит, как подготовить разделители и проверить реплики после перевёрстки.

Транскрибатор
ЗАПИСЬПЛАН РАБОТЫПроверьте границы абзацевЗадайте ширину строкСверьте переходы говорящихПроверить результатОТ СЛОВ К РЕЗУЛЬТАТУ
Работа с реальной записьюНаглядный учебный примерШаблон для копирования
1Проверьте границыабзацев2Задайте ширину строк3Сверьте переходыговорящих
Надёжная граница абзаца сохраняется; внутренняя разбивка строки создаётся заново.

Сначала проверьте структуру исходника

После переноса из редактора TXT иногда содержит короткие строки фиксированной ширины: одна реплика разбита на несколько физических строк. Для дальнейшего чтения или вставки в другой документ полезно переверстать её под выбранную ширину.

Способ ниже подходит только при ясном соглашении: пустая строка отделяет самостоятельный абзац, обычные переносы внутри него — жёсткая разбивка одной реплики. Если каждый говорящий начинается с новой строки без пустого разделителя, такой код склеит их. Сначала подготовьте границы вручную или выберите другой разбор.

Работайте с отдельной paragraphs.txt, сохранив исходник. Полученную через расшифровку аудио сначала проверьте по говорящим и таймкодам. Автоматическая ширина строк не распознаёт смену участника.

Разделите абзацы до вызова fill

textwrap.fill обрабатывает один абзац и возвращает строку с новыми переносами. Если передать ему весь файл, границы самостоятельных реплик могут исчезнуть. Поэтому учебный код сначала разбивает текст по пустым строкам, а потом обрабатывает каждый блок отдельно.

width=80 задаёт желаемую ширину в символах, а не в пикселях браузера. break_long_words=False и break_on_hyphens=False оставляют длинные слова и дефисные формы целиком. Из-за этого отдельная строка может оказаться длиннее 80 символов — это ожидаемое следствие выбранного правила.

Обычные CRLF и CR в рабочей строке сначала заменяются на LF. Если Вам нужно только унифицировать окончания, используйте отдельную нормализацию переносов. Перевёрстка ниже дополнительно меняет пробелы и внутреннюю разбивку.

Создайте перевёрстанную копию

Сохраните код как rewrap.py рядом с paragraphs.txt и запустите python rewrap.py или python3 rewrap.py. Начните с двух учебных реплик, отделённых пустой строкой, и небольшого width, чтобы изменения были заметны.

from pathlib import Path
from textwrap import fill
import re

text = Path("paragraphs.txt").read_text(encoding="utf-8-sig")
text = text.replace("\r\n", "\n").replace("\r", "\n")
blocks = re.split(r"\n[ \t]*\n+", text.strip())
result = []
for block in blocks:
    paragraph = " ".join(line.strip() for line in block.splitlines())
    result.append(fill(paragraph, width=80,
        break_long_words=False, break_on_hyphens=False))
with Path("paragraphs-wrapped.txt").open(
    "x", encoding="utf-8", newline="\n"
) as saved:
    saved.write("\n\n".join(result) + "\n")
print("Абзацев обработано:", len(result))

В этом примере несколько пустых разделителей сводятся к одному, крайние пробелы строк убираются, а переносы внутри блока становятся пробелами перед новой разбивкой. Поэтому его нельзя называть побайтовым сохранением или применять к форматам с содержательными отступами.

Не используйте такой разбор для SRT, таблицы CSV, кода или списка с зависимыми строками. У этих форматов переносы участвуют в структуре, и простое соединение способно её нарушить.

Проверьте слова и переходы между участниками

Сравните число абзацев и начало каждого блока. Проверьте, что подпись второго говорящего не появилась внутри первого ответа. Отдельно просмотрите длинный термин, дефисную форму, таймкод и последнюю реплику.

Для сравнения старой и новой копии полезен HTML-отчёт difflib. Переносы создадут заметные различия, поэтому читайте спорные фрагменты целиком и проверяйте последовательность слов.

Если в конце физической строки стоит дефис переноса из печатной вёрстки, скрипт не угадает, нужно ли его удалить. «транс-» и «крибация» останутся отдельными частями с пробелом. Такие случаи требуют отдельной проверки, чтобы не повредить настоящий дефис в слове.

Учебный пример

Учебный пример: два абзаца остаются двумя

Вымышленный TXT содержит две реплики, между которыми заранее поставлена пустая строка.

ДоОбработкаПосле
А: Обсудим срок поставки.Перенос внутри блока → пробелА: Обсудим срок поставки.
Пустая строкаГраница блокаПустая строка
Б: Подготовлю новый план.Отдельный вызов fillБ: Подготовлю новый план.
ГраницаПустая строкаПроверить до запускаШиринаЖелаемые 80 символовУчесть длинные словаРепликиПорядок и участникиСравнить после записи
Перевёрстка допустима только при заранее подтверждённых границах блоков.

Если в исходнике нет надёжных разделителей, не используйте чистый результат как доказательство сохранённой структуры: сначала исправьте соглашение о входе.

Проверка перевёрстки абзацев

Рабочая заготовкаВыделите и скопируйте
Исходная копия: [имя]
Граница абзаца: [правило]
Все говорящие разделены: [проверено]
Ширина: [число символов]
Длинные слова: [не разрываются]
Абзацев до и после: [числа]
Переходы участников: [контрольные места]
Дефисы переноса: [проверены]
Результат: [имя копии]

Частые вопросы

Можно передать весь TXT в fill?

Если в нём несколько самостоятельных реплик, сначала разделите их на подтверждённые блоки.

Строка длиннее width — обязательно ошибка?

Нет. При запрете разрыва длинных слов отдельное слово может превышать выбранную ширину.

Код сохраняет все пробелы и пустые строки?

Нет. Он меняет пробельное оформление по описанным правилам.

Подходит ли способ для SRT или CSV?

Нет. Для этих структурированных форматов нужен отдельный разбор.