Как pdf (изображения) преобразовать в текстовый txt-файл

Вы скажете, что самый простой способ — выделить весь текст в pdf, скопировать его в буфер обмена и вставить из буфера обмена в текстовый файл. И будете правы. Но это не наш случай. Файл pdf — результат сканирования многостраничного документа. Т.е. содержимое pdf — это изображения текста.

image


Предлагаемый вариант решения реализован под Windows-8, но с небольшими корректировками, думаю, вполне может быть использован для Linux и OS X.
С задачей преобразования изображения в текст справляются Abbyy FineReader, MS Word, MS OneNote. Существуют также сайты, на которых изображение можно преобразовать в online: http://www.ocrconvert.com
Предлагаемое решение использует бесплатные утилиты. В приоритете также была работа в командной строке.

Преобразование всех страничек pdf в файлы изображений


Если бы страничек было 2-3, то можно было бы воспользоваться функцией PrintScreen. В Windows для этого есть отдельная кнопочка на клавиатуре. А в Mac OS X — хитрая комбинация клавиш: нужно нажать три клавиши Shift+Command+4, выбрать мышкой нужный участок экрана, и искать получившийся файл на рабочем столе. Но если страничек много, то нужно искать другой способ.

К счастью, есть программа StduViewer, которая позволяет это сделать. В меню Файл → Экспортировать → Как изображение. В появившемся окне выбираем тип PNG, разрешение 300 dpi, задаем путь, куда выложить получившиеся файлы изображений. В шаблоне имени сохраняемого файла стоит изменить %PN% на %0PN% для случая, если страничек больше 10.

kolgrim99 предложил для конвертации pdf-документа в jpg-файлы утилиту из пакета xpdf, которую можно использовать в командной строке. Вот его предложение:
<<Если стоит задача просто выпотрошить большой PDF файл со сканами (или любыми другими картинками), то можно использовать утилиту из набора xpdf, там куча всего, но для картинок нужна pdfimages.exe. Синтаксис примерно такой:
pdfimages.exe -j some_file.pdf C:\images\

причём в последнем аргументе в конце пути обязательно ставить '\', иначе не воспримет.>>

Преобразование файлов изображений страничек в текст


HP разработала, а Google открыла исходные коды библиотек tesseract, преобразовывающих изображения в текст (OCR). Устанавливаем программу tesseract-ocr.
Для распознавания русского языка при установке нужно в «Additional language data» взвести галочку для Russian.

В командной строке исполняем команды типа:

tesseract.exe image_01.png res_01.txt -l rus

Получаем текстовые файлы. Можно запустить команду для каждой странички вручную. Проще выполнить скрипт на python'е:

import os, sys
import io
sPathIn = "D:/Pictures/pict"
sPathOut = "D:/Pictures/txt"
sCmd = "\"C:/Program Files (x86)/Tesseract-OCR/tesseract.exe\" {} {} -l rus"
os.system("cd \"C:/Program Files (x86)/Tesseract-OCR\"")
dirs = os.listdir( sPathIn )
for file in dirs:
 filename, file_ext = os.path.splitext(file)
 sCmdRes = sCmd.format(sPathIn + '/' + file, sPathOut + '/' + filename + ".txt")
 print ("run> " + sCmdRes)
 os.system(sCmdRes)

Получилась кучка текстовых файлов, которые осталось объединить в один. Это можно сделать ручками. Но проще было написать скриптик на python'е:

import os, sys
import io
sPathIn = "D:/Pictures/txt"
sFileOut = "D:/Pictures/res.txt"
dirs = os.listdir( sPathIn )
for file in dirs:
 filename, file_ext = os.path.splitext(file)
 if (file_ext == ".txt"):
  fOut = open(sFileOut, "ab")
  f = open(sPathIn + "/" + file, "rb")
  data = f.read()
  fOut.write(data)
  f.close()
  fOut.close()

На этом можно было бы закончить, т.к. в основном текст получился вполне читабельным, но местами в тексте образовалась масса оЧЕпЯток.
Например, картинка с текстом

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

Поэтому появился следующий этап.

Исправление ошибок в тексте


Воспользуемся программой LanguageTool. Нас интересует работа в командной строке, поэтому скачиваем «независимую версию». Для работы с LanguageTool требуется Java.

Запускал из родного каталога (на Windows-8.1 оно почему-то не захотело работать, если текущий каталог — чужой) и указывал полные имена файлов (с каталогом). Если в командной строке выполнить команду, например, такую:

java -Dfile.encoding=UTF-8 -jar languagetool-commandline.jar --help

… то запустится дополнительная консолька, где честно напишет help и благополучно закроется в течение секунды. Чтобы видеть, чего же оно пишет в консоль, нужно запускать командный bat-файла с этой строкой внутри. Возможно, у java есть ещё какой-нить параметр командной строки, чтобы не запускалась доп. консоль, но мне сие неведомо.

Команда исправления ошибок в текстовом файле получилась такая:

java -Dfile.encoding=UTF-8 -jar languagetool-commandline.jar -a -l ru original.txt > corrected.txt

Чтобы отключить исправление маленьких букв на большие в начале строк появились дополнительные параметры --disablecategories CASING, а вместо имени файла — %1, чтобы имя передавать внутрь bat-файла в качестве аргумента. Итого, строка в bat-файле получилась такая:

java -Dfile.encoding=UTF-8 -jar languagetool-commandline.jar -a -u --disablecategories CASING -l ru %1 > %1-res.txt

По аргументу -u в конец исправленного текстового файла добавляется строка «Unknown words:» с перечислением через запятую всех слов, которые LanguageTool не знает. Таким образом, можно улучшить текст, исправив неправильные слова из этого списка.

Был использован Python 3.5 и PyCharm.
Спасибо за внимание!
Поделиться публикацией
Комментарии 60
    0
    Есть пример входного и выходного файла для которого это работает?
    А то я по-быстрому заскринил статью из opennet — прогнал скрин через tesseract 3.03 — получилась редкостная чушь.
    А ещё, подозреваю, что таблицы оно не понимает… никак…
      0
      Пример картинки и результат полученного текста привел в статье.
      Насчёт таблиц — не знаю, не пробовал.
        0
        А ещё совсем плохой текст получался, когда я скормил tesseract'у картинку с разрешением < 300 dpi.
        0
        Со скриншотами вечная проблема. Количество пикселей на букву очень мало, если сравнивать с фотографией или сканом страницы.
        +1
        Берём FineReader и всё, пусть местами и кривовато, работает.
          +3
          И получим наиболее качественный вариант.
          Одна только проблемка. Оно денег хочет (страничек у нас по условию задачи много).
          Есть бесплатный вариант. Cuneiform. Качество будет средней паршивости.
            0
            У Cuneiform и со стабильностью проблемы при пакетном распознавании. :(
            +3
            Берём Покупаем FineReader, Вы хотели написать?
              0
              Лично у меня всё уже куплено. Возможно не только у меня!
                0
                А. В таком случае, претензий не имею :)
                0
                И я, читая, вспомнил про FineReader. Доволен его работой. (Правда, распознавать приходится не часто).
                  0
                  Владельцам МФУ на заметку. Раньше тоже «брал» FineReader, но как-то от нечего делать шарился по дампам CD дисков с драйверами и в одном из дисков от МФУ обнаружил инсталлятор очень приличной платной распознавалки, называлась Read Iris (согласно лицензионному соглашению её можно было использовать вместе с МФУ, была фулл версия, русский + английский, с логотипом HP в инсталляторе и без всяких серийников), а на другом диске от второго МФУ обнаружилась какая-то версия FineReader. С тех пор проблема с лицензией для меня отпала.
                +2
                Отличная статья. Только сегодня ночью прикручивал tesseract к telegram, skype и whatsapp ботам. Спасибо за идею с исправлением ошибок. Клиенты нашей CRM сильно обрадуются этой функции, другим разработчикам советую взять на заметку.

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

                Также она умеет распознавать штрихкоды, фотографии ценников в магазинах от мерчика сразу с геометкой уходят в базу клиента в структурированном виде. Только один раз немного нужно подрихтовать распознавание под каждую сеть магазинов.
                  +5
                  Честно говоря, по своему опыту, если вижу на горизонте задачу «сделать экспорт отчетов в PDF» или, упаси Нортон, «перевести документы с таблицей из PDF во что-то другое» — предпочитаю сразу избавиться от этой задачи…
                  Если с экспортом еще можно что-то придумать через различные html2pdf-утилиты разной степени ущербности, то парсинг PDF — это тот еще адок… Внутренняя структура представляет из себя набор блоков контента с координатами. Причем в блоке могут быть как отдельные буквы, так и столбцы (!) букв. Преобразовать это все во что-то машиночитаемое, поверьте мне, не так легко.
                  Блоки могут перекрываться, но на экране этого не видно, однако при парсинге вы наверняка выучите размеры ширины и высоты всех символов используемых шрифтов.
                  Интересная идея перевести PDF в картинку и распознать. Однако, любое распознавание — это, как и замечено в статье, — с определенной вероятностью путь к опечаткам. Если процесс надо автоматизировать, а в файлах содержатся цены или точные данные — то любые опечатки могут быть довольно болезненны. Тем более что в PDF, вроде бы, есть эти данные и использовать их — вроде бы логичнее.

                  Что касается html2pdf — на первый взгляд все выглядит довольно удобно. Утилит и библиотек достаточно много разных. Вроде бы и html в виде странички с отчетом у вас уже есть, но не все так просто…
                  Внезапно оказывается, что стили этот конвертор понимает по-своему, некоторые css-фичи не поддерживаются совсем, выкидывая в процессе критическую ошибку на "@" символы. Да и результат почему-то оказывается совсем не таким как на экране — все плывет и не умещается на экран… Стили из bootstrap совершенно не работают…
                  Ах да, у нас на страничке были графики из chart.js? Клиенту они очень нравятся и он хочет их тоже видеть в отчете? Okay…

                  Для конечного пользователя PDF выглядит очень удобным, переносимым, удобным при печати, поэтому его и просят везде. Но работать с ним изнутри… Ну нафиг…

                  Как это было у меня
                  У меня был следующий опыт — изначально задача ставилась как «отобразить отчеты с фильтрами на страничке из базы». Довольно просто, ок.
                  После этого клиент просит добавить графики. Ок, chart.js выглядит красиво — делаем. Рисуем на фронтенде, данные приходят через API.
                  Внезапно следующая просьба — сделать экспорт один-в-один в csv/xls/pdf. Чувствую, что это не так уже просто. CSV — это текст, не проблема… XLS умеет графики сам рисовать довольно просто, тоже решается.

                  А вот с PDF начинается цирк. Допустим, таблицы с грехом пополам я там нарисовал, а вот для графиков придумал «грязный хак» — при клике юзером кнопки «PDF» все графики на страничке жабаскриптом переводятся в картинки и отправляются на бэкенд, где просто вставляются в PDF. Выглядят так же и чертить оси-масштабы-легенды не надо.

                  Я понял что идея была плохой, когда клиент в следующий раз попросил сделать 'njn экспорт по расписанию автоматически, отправляя отчет по почте с PDF-вложением… Эту задачу решал уже не я, а другой разработчик, который это сделал через matplotlib.
                    0
                    Речь в статье о pdf, который содержит не текст, а картинки, т.е. отсканированный документ.
                      0
                      Да, виноват, не обратил внимания на именно этот факт. Это меняет дело.
                      Заголовок можно бы поправить на «как картинки из pdf преобразовать в текстовый файл» — тогда будет точнее отражать суть.
                        0
                        Подкорректировал. Спасибо за совет. Надеюсь, стало понятнее.
                      +2
                      Та ладно… Из HTML в PDF достаточно простая задача. Только не надо съезжать в «быстрые» решения вроде html2pdf.

                      PDFCreator же как-то в PDF печатает. Браузеры могут, LibreOffice может. Просто задействовать API существующих программ.

                      Как лобовой вариант (возможно, сейчас не самый эффективный): сохранить html с картинками на диск, открыть с помощью LibreOffice API, сохранить с помощью LibreOffice API в PDF. Точнее, даже сохранять на диск не обязательно, можно прямо с http открыть. Возможно, сейчас эффективнее будет задействовать API браузеров (не знаю, не пробовал).

                      Я в своё время прошёл следующую эволюцию:
                      1. Html2pdf (говно).
                      2. Apache FOP. Может преобразовывать XSL-FO в PDF. XSL-FO — это специальный язык разметки (аналогичный HTML, только для разбиваемых на страницы документов, а не бесконечно вертикально протяженных; т.е. те нюансы форматирования, которые html2pdf пытается решить введением дополнительных keyword'ов в HTML и соответственно отходом от полноценной поддержки нормального HTML, при использовании FOP решены системно использованием стандартизованного и продуманного языка). Навострившись в XSL-FO, можно генерить документы прямо в нём.
                      3. OpenOffice.org (тогда ещё не было LibreOffice) API.

                      При этом можно автоматически преобразовывать ODF-документы в XSL-FO, установив в OpenOffice некоторые расширения (по сути, XLST-фильтры, добавляющие поддержку дополнительных форматов). Это если захотите комбо 3+2. А ещё ODF-документы можно генерить напрямую.

                      P. S.: А обратно да, обратно конечно нафиг, не стоит
                        +1
                        Я недавно открыл для себя athenapdf

                        Честно говоря, решение довольно громоздкое, но результат рвёт html2pdf как тузик грелку, да и в использовании гораздо проще
                        +5
                        Самый простой и качественный для меня вариант был открыть файл PDF Word'ом. Который 365. Он при открытии PDF файла его распознает. И почему-то распознает у меня лучше, чем FineReader. А так как Word входит в комплект офиса, который у меня и так стоит, то файнридером я больше не пользуюсь.
                          –2
                          Речь в статье о pdf, который содержит не текст, а картинки, т.е. отсканированный документ. Word не умеет из картинок делать текст. FineReader умеет.
                            +2
                            вообще-то именно картинки и распознавались, сами попробуйте.
                              +2
                              http://rgho.st/8zPF4Rfw6 исходный PDF
                              http://rgho.st/7pzTWYvbf файл, который создал сам Word 365 (он же 2016)
                                +1
                                Да, действительно. Не знал, что они 365-й Word обучили преобразовывать в текст. Спасибо за информацию.
                                А ошибки там, кстати, такие же, как и в случае с tesseract'ом. Например, слово «также» превратилось в некое «таюке» :). Так что исправление опечаток все ещё актуально.
                                  +1

                                  Офис довольно давно умеет распознавать текст. Используя бесплатную OneNote, получить текст из PDF можно в 2 клика:


                                  1. Вставка -> Распечатка.
                                  2. ПКМ по любой странице -> Копировать текст со всех страниц.

                                  Аналогично можно распознавать и другие форматы, например DJVU, открыв документ в соответствующем приложении и отправив на печать на виртуальный принтер OneNote.

                                    0
                                    Да, хорошее, простое решение — ставлю «лайк». Но если бы я выбрал такое простое решение, то на python'е не удалось бы попрограммить :). И ещё плюс моего решения — практически все вопросы решаются из командной строки (т.е. можно автоматизировать процесс при желании), с небольшими допилами можно использовать на других операционных системах. И кроме того, от последнего этапа — исправление ошибок — OneNote, скорее всего, не избавляет. Или по опыту текст совсем чистенький получается?
                            +6
                            Здравствуйте! Я из ABBYY. Наши разработчики прочитали ваш комментарий и просили передать, что завели рекламацию и будут исправлять этот момент в файнридере.
                              +4
                              Abbyy просто молодцы — мгновенная реакция
                                +1
                                Здравствуйте!
                                Пользуясь случаем, во-первых хочу поблагодарить за удобную программу (FineReader), а во-вторых подкинуть идею вашим разработчикам. Для математических текстов (в том числе и текстов по CS, нпр., с описанием алгоритмов) очень часто используют TeX/LaTeX. Но иногда текст доступен только в pdf. Вот бы сделали возможность распознавать с мат. формулами в TeX/LaTeX, а то, нпр., часто бывает необходимость цитировать мат.тексты.
                                  0
                                  PS Один из примеров такого цитирования это Википедия.
                                    0
                                    Всё никак не соберёмся делать распознавание математических формул — никто не верит, что дело окупится.
                                    Косвенное свидетельство тому — пока нет хорошо работающего изделия из говна и палок перебора гипотез отношений и Tesseract'а.
                                +1
                                Жесть какая, зачем питон тут вообще? Раз уж под винду, так хотя бы powershell, учитывая, что из коробки.
                                  0
                                  Винда под рукой была. powershell — не умею и не интересно. А на python'е интересно.
                                  0
                                  Кстати, а что если так: берем пдф, который текстом, блоками, фигачим его в картинки, сохраняем разметку где картинке какой блок соответсвует и полу-распознаем текст. То есть по сути, мы просто через преобразование в картинку и распознавание картинки визуально переделываем блоки пдф. В итогде можно получить почти безошибочный документ. Ошибок распознавания символов не будет, будет беда только с ошибками распознавания таблич, содержаний и наверное структуры заголовков, пометок страниц — номера, имя главы.

                                  Я очень давно хочу получить тулз для переваода пдф в нормальные электронные документы. Если речь идет об электронных книгах, то в основном предлагают вариант, где каждая строка пдф — это отдельный абзац. И текст получается фиксированной ширины.
                                    0
                                    Что значит «сохраняем разметку где картинке какой блок соответсвует»?
                                      –2
                                      1. Берём PDF. Желательно крупный. Желательно на нескольких языках.
                                      2. Конвертируем его в pdf-картинки (сохраняя оригинал).
                                      3. Обучаем исходниками и результатом нейросеть
                                      4.…
                                      5. Profit!
                                      0
                                      del
                                        0
                                        Сергей, а как связаться с Вами можно?
                                        Хочу посоветоваться, есть похожая задача на распознавания товаров и цен к ним из PDF.
                                          +2
                                          Если стоит задача просто выпотрошить большой PDF файл со сканами (или любыми другими картинками), то можно использовать утилиту из набора xpdf, там куча всего, но для картинок нужна pdfimages.exe. Синтаксис примерно такой:

                                          pdfimages.exe -j some_file.pdf C:\images\

                                          причём в последнем аргументе в конце пути обязательно ставить '\', иначе не воспримет.
                                            0
                                            Спасибо за полезную идею!
                                            +3
                                            Получилась кучка текстовых файлов, которые осталось объединить в один. Это можно сделать ручками. Но проще было написать скриптик на python'е

                                            А можно просто одной командой: copy *.txt vestext.txt
                                              –2
                                              Ага. Полностью согласен. Предложенная Вами команда гораздо короче, поэтому быстрее. Мне просто было интереснее сделать это на python'е :). И есть ещё один хороший плюс у python'овского кода — кроссплатформенность. Т.е. его можно выполнить на Windows, OS X, Linux, и т.д.
                                                0
                                                ваш код на питоне просто ужасен:
                                                • он не кроссплатформенный, чего только стоит разделитель путей '/'
                                                • в строках запутывающие экранирования, когда можно просто использовать одиночные кавычки
                                                • открытие файла без with или try
                                                • ой, всё

                                                  0
                                                  Так не было намерений написать красивый, в рюшечках код. И, возможно, у нас с Вами разные представления о том, что такое ужасно, а что такое прекрасно :). Это ж дело вкуса. Возможно, если Вы выложите здесь пример Вашего совершенного кода, он может показаться кому-то ужасным. То, что я написал — это одноразовый код — написал, получил результат и забыл. Если у Вас есть желание его повторно использовать, и сделать кроссплатформенным с обработкой исключений — пожалуйста. Только это потребует дополнительных строчек кода, а значит — времени. Может, это не очень красивый код, зато это код проверенный и работающий. Вы можете его использовать прям сходу для решения целевой задачи. Ну, и что там говорить — в python'e это мои первые шаги, поэтому где-то могу писать не оптимально.
                                                    0
                                                    1) А чем плох разделитель путей '/'? Этот-то как раз более кроссплатформенный, чем такой — '\\'. И ещё вот такой '/' лучше, потому что не требует «запутывающего экранирования». Так что отметаю полностью это Ваше замечание. Пока не представите более убедительные доказательства ужасности прямого слэша.
                                                    2) Насчёт одинарных кавычек — согласен. Можно было. Мне просто привычнее двойные.
                                                    Имеется ввиду, как я понимаю, такое использование кавычек:
                                                    sCmd = '"C:/Program Files (x86)/Tesseract-OCR/tesseract.exe" {} {} -l rus'
                                                    
                                                    3) И насчёт with — в принципе согласен. С файлами лучше использовать его. Даже в коде на скорую руку. По крайней мере потому, что вызов close тогда не нужен. Имеется ввиду такой код:
                                                    with open(sFileOut, "ab") as fOut:
                                                    
                                                      +1
                                                      1) разделитель путей "/" плох тем, что это магическая переменная. возможно в виндовсе она будет работать. но лучше использовать os.sep, который точно будет работать в той системе, в которой выполняется код. ещё лучше использовать os.path.join() для того, чтобы составлять путь.

                                                      2) да.

                                                      3) да.

                                                      код должен быть красивым и понятным, если его показывать людям.
                                                      если код красивый и понятный, его можно понять и через год.
                                                        0
                                                        Разделитель "/" будет работать в Windows, Linux, OS-X. Согласен, что в идеальном коде нужно использовать os.sep. Но в неидеальном одноразовом коде, когда закопипастить путь (как я и сделал в приведенном коде) проще, чем составлять путь из кусочков. Наглядность, кстати, тоже пострадала бы, если бы я использовал не слэши (на мой взгляд). Хотя, конечно, пути лучше в коде не хранить, держать их где-нить в конфигах. Тогда отпадет необходимость в использовании слэшей в коде. Так что принципиально с замечанием согласен.

                                                        <<код должен быть красивым и понятным, если его показывать людям.
                                                        если код красивый и понятный, его можно понять и через год.>> — золотые слова!!! подписываюсь под каждой буквой!
                                                –1
                                                sudo apt-get install poppler
                                                pdftotext input.pdf output.txt

                                                </thread>
                                                  0
                                                  А ничего, что исходные PDF не содержат текстового слоя?
                                                  В функции pdftotext не входит OCR.
                                                    0
                                                    И еще один человек читает только заголовки, да и то не целиком
                                                    0
                                                    А русский язык к tesseract как подключили?
                                                    У меня ругается
                                                    Failed loading language 'rus'
                                                    Tesseract could't load any language
                                                      0
                                                      Для распознавания русского языка при установке tesseract'а нужно в «Additional language data» взвести галочку для Russian. Если не поможет, т.е. русский уже установлен, то попробуйте сделать текущим каталогом tesseract.
                                                      0
                                                      У меня нормально tesseract распознал приведенную картинку (OS X 10.8).
                                                      временного прерывания, промежуточного сохранения и повторного запуска
                                                      процесса моделирования из приостановленного состояния, задания различных
                                                      начальных условий, ввода отказов бортовых систем, метеоусловий, времени

                                                      суток, различных возмущающих факторов (ветер, турбулентность и др.);

                                                      У Вас как-то неправильно обрабатываются концы строк.
                                                        0
                                                        Приведённый текст — это часть странички, которую tesseract должен был преобразовать. Может, tesseract лучше отрабатывает, если ему скармливать меньше текста? Загадка.
                                                          0
                                                          Нет, тут вопрос не в кусочке страницы, а в обработке концов строк. Все приведенные в примере ошибки связаны лишь с тем, что пропали концы строк. Скорее всего, это связано с тем, tesseract выдает в unix-формате только с LF, а windows хочет видеть CR+LF. Посмотрите в википедии, там есть и подсказки, как это поправить.
                                                            0
                                                            Там ещё и слова отличаются: «введа» VS «ввода».
                                                              0
                                                              Да, это Вы хорошо подметили — насчёт концов строк. Посмотрел. Tesseract выдает текст в кодировке utf-8. Перевод строк — два символа \x0A+\x0A. Там, где в результате работы tesseract слова без пробела — один символ \x0A. Ну, с этой проблемой легко справился LanguageTool. Спасибо за замечание!
                                                                0
                                                                > два символа \x0A+\x0A
                                                                Я думаю, это абзац. а просто перевод строки — одинарный \x0A.
                                                                (Если Вы, конечно, не опечатались, имея в виду \x0D+\x0A.)
                                                                  0
                                                                  не опечатался — именно два одинаковых символа \x0A
                                                                    0
                                                                    Ну, это точно не перевод строки.

                                                                    Это абзац.

                                                                    _Два_ Enter'а.

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

                                                        Самое читаемое