LINUX.ORG.RU

Как переформатировать «книжные» абзацы с переносами в длинные строки?

 ,


0

1

Имеется текст, в котором абзацы разбиты на строки, причем в словах имеются переносы. Выглядит текст вот так:

Это такой текст в котором есть переносы
строк. Причем строки переносятся не толь-
ко на границах слов, но и с помощью сим-
волов переноса (символ "тире").

Каждый абзац отделяется от другого пустой
строкой.

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

Каждый абзац отделяется от другого пустой строкой.

Как это можно быстро сделать? Есть ли готовые утилиты? Может быть, есть какой-то сервис онлайн?

★★★★★
Ответ на: комментарий от Zhbert

Можно чуть усложнить — сначала берешь какой-нибудь awk или sed и бежишь по строкам, убирая в конце дефисы, если они есть. А потом см выше.

Zhbert ★★★★★
()
Последнее исправление: Zhbert (всего исправлений: 1)

Быстро - полностью от тебя зависит, средненького знания bash достаточно.

Если пустая строка, то переходишь к следующей. Начало абзаца.

Проверяешь символ «конца строки». Если «да», проверяешь предыдущий символ. Если «перенос» - удаляешь. Удаляешь символ конца строки.

Тут конечно возможны «какие-нибудь» коллизии.

andytux ★★★★★
()
Ответ на: комментарий от vvn_black

Я перебрал штук 15 онлайн-сервисов, и нашел пока один, который делает почти то что нужно:

https://ru.texthandler.com/text-tools/remove-line-breaks/

Переносы строк и удаление символов переноса (тире) сервис делает правильно.

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

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от uwuwuu

perl -p -e 's/\n(?![^\n])/ /' file

И получили месиво:

Это такой текст в котором есть переносы строк. Причем строки переносятся не толь- ко на границах слов, но и с помощью сим- волов переноса (символ "тире").  Каждый абзац отделяется от другого пустой строкой.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Avial

предварительно замени (или добавь) к двум \n\n еще какой-нибудь произвольный символ (например ^) потом замени его обратно на пустую строку.

А если он встречается в тексте?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

я его тоже не знаю. там регулярки:

's/шаблон для замены/чем заменяем/'

's/\n(?![^\n])/ /'

# Перенос строки после которого идет любой символ кроме переноса
\n(?![^\n])
uwuwuu
()
Ответ на: комментарий от Xintrea

нельзя настроить чтобы между абзацами оставалась пустая строка.

Возьми результат и напечатай строчки из него добавляя после каждой перевод строки.

sin_a ★★★★★
()

Мракобесы вы все какие-то :) Я самый простой вариант предложил.

  1. Сохрани текст в text.txt
  2. Бахни его седом, убрать дефисы в конце строк: sed 's/-$//' text.txt > output.txt
  3. Убедись, что в output.txt все нормально:
Это такой текст в котором есть переносы
строк. Причем строки переносятся не толь
ко на границах слов, но и с помощью сим
волов переноса (символ "тире").

Каждый абзац отделяется от другого пустой
строкой.
  1. Переименую его в *.md: mv output.txt output.md
  2. Открой в VSCode и жамкни просмотр. Скопируй оттуда то, что тебе нужно:
Это такой текст в котором есть переносы строк. Причем строки переносятся не толь ко на границах слов, но и с помощью сим волов переноса (символ "тире").

Каждый абзац отделяется от другого пустой строкой.
Zhbert ★★★★★
()
Ответ на: комментарий от vvn_black

sed ':a;N;$!{/\n$/!ba}; s/[[:blank:]]*\n[[:blank:]]*/ /g; s/-\s//g; G' filename.txt

Во, это самое правильное решение. Ну я уже в полуручном режиме обработал нужный мне текст.

Xintrea ★★★★★
() автор топика
Последнее исправление: Xintrea (всего исправлений: 1)
Ответ на: комментарий от vvn_black

sed ':a;N;$!{/\n$/!ba}; s/[[:blank:]]*\n[[:blank:]]*/ /g; s/-\s//g; G' filename.txt

Хотя нет, тоже есть косяк с лишними пробелами в начале абзаца. Это как-то связано с переносом в первой строке абзаца.

А так же в конце абзаца всегда остается лишний пробел.

Xintrea ★★★★★
() автор топика
Последнее исправление: Xintrea (всего исправлений: 2)
Ответ на: комментарий от vvn_black

sed ':a;N;$!{/\n$/!ba}; s/[[:blank:]]*\n[[:blank:]]*/ /g; s/-\s//g; G' filename.txt

В общем, более правильно будет сделать так:

cat filename.txt | sed ':a;N;$!{/\n$/!ba}; s/[[:blank:]]*\n[[:blank:]]*/ /g; s/-\s//g; G' | sed 's/^[ \t]//' | sed 's/[ \t]$//' > newFilename.txt

Понятно, что это всего лишь исправление постфактум неправильного базового алгоритма, но результат получается такой какой нужно.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Я даже не проверял:

$ xclip -sel c -o | perl -p -e 's/\n{2}//'
Это такой текст в котором есть переносы
строк. Причем строки переносятся не толь-
ко на границах слов, но и с помощью сим-
волов переноса (символ "тире").

Каждый абзац отделяется от другого пустой
строкой.

$ xclip -sel c -o | perl -p -e 's/\n/_/'
Это такой текст в котором есть переносы_строк. Причем строки переносятся не толь-_ко на границах слов, но и с помощью сим-_волов переноса (символ "тире").__Каждый абзац отделяется от другого пустой_строкой.

Perl тоже как-то странно работает. Он два переноса не воспринимает

uwuwuu
()
Ответ на: комментарий от Xintrea
$ xclip -sel c -o | perl -p -0 -w -e 's/\n\n/<br>/g; s/-\n//g; s/\n/ /g; s/<br>/\n\n/g'
Это такой текст в котором есть переносы строк. Причем строки переносятся не только на границах слов, но и с помощью символов переноса (символ "тире").

Каждый абзац отделяется от другого пустой строкой.
uwuwuu
()
Ответ на: комментарий от Xintrea

Мысль такая, что вы дольше топик на ЛОРе создавали, минута поискать «linux unwrap|unfold text» и потом за полчаса допилить после тестов, подчистить.

Но это не в плане упрёка, бывает, что накатывает какой-то стопор, который не даёт даже направление решения самостоятельно увидеть. Я с этим стараюсь бороться.

vvn_black ★★★★★
()
Ответ на: комментарий от vvn_black

А вот откуда можно узнать, что нужно делать «linux unwrap|unfold text»?

Я, например, искал «linux text remove line breaks paragraph transfer symbol how to formatting» и прочие комбинации.

Основная проблема с «transfer symbol», про них как будто все забывают.

Xintrea ★★★★★
() автор топика

Я когда то в промышленных масштабах такое делал, когда приносили монографию в txt и её нужно было запихать в пижмекер и сверстать. Собсно правильную логику тут уже подсказали выше, неоднократно.

PS. Это всё детские неприятности по сравнению с монографией набранной в Microsoft Word, со встроенными туда пережатыми иллюстрациями в 72 DPI, разъехавшимися таблицами и сбитой нумерацией страниц. И сопровождающим её распоряжением «автор сам её сверстал, просто быстренько к печати подготовьте и в печать, там всё сделано практически».

Jameson ★★★★★
()
Последнее исправление: Jameson (всего исправлений: 4)
Ответ на: комментарий от dmitry237

За дефисом обычно следующий печатный символ следует. А за переносом следует непечатный символ CR, или LF, или CR+LF в зависимости от того в какой ОС сохранялся txt. Возможно конечно что перенос произошёл на самом дефисе, но подобные вещи всё равно глазами отлавливать нужно. Вообще автозамены лучше делать по абзацам с визуальным контролем результата, иначе может быть грустно, либо смешно.

Jameson ★★★★★
()
Последнее исправление: Jameson (всего исправлений: 1)
Ответ на: комментарий от dmitry237

Я видимо тогда твоего вопроса не понял. Ты спросил как отличить перенос от дефиса. Я понял так:

бледно-розовый (это дефис)

индустри-
ализация (перенос)

бледно-
розовый (перенос попал на дефис)

Логика такая — сначала мы отлавливаем и убираем именно переносы, их признаком является то что после - следует символ перевода каретки или возврата строки, или оба два одновременно (зависит от ОС в которой сохраняли txt). В третьем примере мы не отличим перенос от дефиса, но во первых словосочетания с дефисом редкость, а во вторых вычитку после автозамен никто не отменял.

Ну а дальше, избавившись от переносов, мы поабзацно избавляемся от символов перевода каретки и\или возврата строки, осуществляя тем самым unfold.

Jameson ★★★★★
()
Ответ на: комментарий от Jameson

но во первых словосочетания с дефисом редкость

Не такая уж и редкость, но для часто используемых можно применить правило, а-ля:

$ 'что-то кто-нибудь пере-нос кто-либо' -replace '(?!=-)-(?!(то|нибудь|либо))'
что-то кто-нибудь перенос кто-либо

А оставшиеся исключения уже руками.

dmitry237 ★★★★
()
Ответ на: комментарий от Xintrea

А потом по хорошему всё равно надо ещё раз проходить фильтром убирающим пробелы в начале абзацев, двойные (и более) пробелы тоже. Потому что те кто тексты в txt сохраняют в таком вот как у тебя виде — они ещё пятью пробелами абзацы выделяют, выравнивают заголовки и вообще ими текст форматируют. Так что от всех лишних пробелов тоже нужно избавляться.

Jameson ★★★★★
()
Последнее исправление: Jameson (всего исправлений: 1)

Для FAR Manager есть зачётный плагин Format Block. (Я, кстати, начал писать что-то подобное для mc, пока написал только форматтер по отдельным абзацам, тебе же, как я понимаю, нужно весь текст разом. А вот в Format Block можно выделить и обработать весь текст разом.) Я, правда, Format Block использовал только для обратной задачи — отформатировать текст по ширине, но у него куча настроек, можно глянуть.

Смущает вот это:

Причем строки переносятся не только на границах слов, но и с помощью символов переноса (символ «тире»).

Ну во-первых, если уж на то пошло, перенос внутри слов это, скорее, дефис, чем тире. Но в текстовых файлах одно часто используется вместо другого, так что это можно считать придиркой.

Гораздо хуже другое: что будет после автоликвидации переносов с такими конструкциями, как «стоп-кран», «заказ-наряд» или даже банальным «кое-как»? Видимо, получится именно «коекак». В обоих смыслах. (c) АБС

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от hobbit

Видимо, получится именно «коекак».

Использовать в тексте «неразрывный дефис» или использовать в алгоритмах словари.

https://ru.wikipedia.org/wiki/Дефис

https://symbl.cc/ru/2011/ Неразрывный дефис

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 3)
Ответ на: комментарий от hobbit

P.S. А, выше для ложных переносов уже предлагали ручную вычитку. Боюсь, что для большого текста — не решение, если «бледнорозовый» уже слили, глазами его запросто можно и пропустить.

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

Но это точно не однострочник на перле.

hobbit ★★★★★
()
Ответ на: комментарий от dataman

Произвольных плагинов — нет. Но в mcedit есть возможность подключить внешнюю программу форматирования. Я свой текущий так и подключаю.

Правда, на какой-либо интерактивности при этом приходится поставить жирный крест, и если настройки форматёра можно брать откуда-то ещё, то с двухпроходным форматированием, которое я предложил выше — уже облом. :(

hobbit ★★★★★
()