В строках мы в будущем научимся искать текстовые данные, которые содержит в себе PDF документ. Массивы. Массивы в PDF заключаются в квадратные скобки и представляют собой просто последовательность группированных объектов. Массивы подчас содержат текстовые строки. Словари. Это обрамлнные в lt lt и пары ключ значение. Словарь часто используется для наделения объекта, который его содержит, свойствами, что описаны в dictionary. Нам же эти данные помогут определить, как, например, расшифровать поток, узнать его длину или, наоборот, отбросить текущий объект, как неинтересный если это изображение. Перед вами пример обычного PDF словаря lt lt. После чтения, мой код представит его в виде dictionary array. Любые бинарные данные, будь то сжатый текст, изображение или внедрнный шрифт, будут представлены в виде потока. Поток всегда находится внутри объекта чуть ниже и характеризуется, как минимум, своей длиной опция Length N в словаре и очень часто методом сжатия например, Filter Flate. Decode. PDF поддерживает достаточное количество форматов сжатия в том числе и формат шифрования Crypt. Decode, нас же будут интересовать лишь три наиболее часто используемый Flate gzip сжатие и более редкие ASCII Hex представление данных в виде шестнадцатеричной строки с конечным символом и ASCII 8. Пример потока вы можете найти во второй половине изображения, что вначале данного топика да да, те крякозябрики это оно и есть. Объекты. Объекты это наибольшая структура, с которой на предстоит работать. Объект может содержать внутри себя любой другой тип данных от обычного числа до потока, обрамляется ключевыми словами obj и endobj. Объект имеет свой ID внутри документа, по которому можно на него ссылаться. Нам в первую очередь интересны объекты с потоками внутри себя не забываем об основной подзадаче, которые почти всегда содержат ещ и набор дополнительных опций в виде словаря. Вот обычный пример объекта внутри PDF файла с несжатым содержимым потока 2 0 obj. Td A short text stream. Tj. Что ж на этом вводная часть по внутреннему представлению данных закончилась, переходим к лакомым штукам получение текста из потока, а также получения словарей внутренних преобразований символов реализацию которого я не встречал доселе. Где искать текст Обычно имеется ввиду, сжатые gzip, потоки, но документация говорит нам потом может не сжат вообще или, наоборот, сжатий может быть несколько Filter Flate. Decode ASCIIHex. Decode. Что ж нам нужен какой нибудь действительный пример. Пожалуйста, стихотворение Михаила Юрьевича Лермонтова Парус в PDF формате документ создан на Acrobat. Найдм в данном документе какой нибудь объект и начнм его разбирать. Я немного смухлюю и возьму объект, в котором заведомо есть текстовые данные, но это только для примера скрипту вс равно с чем работать Давайте для начала разбермся, что перед нами, используя полученные ранее знания о типах данных PDF. Перед нами объект со словарм свойств, которые говорят, что длина потока данных 6. Length 6. 81, что поток сжат Filter в gzip Flate. Decode. Уже достаточно информации, чтобы разжать поток данных подойдт gzuncompress 0. W n. 5. 6. 8 7. 16. Td F1 1. 8 Tf. Нам нужно запомнить всего несколько вещей Если текст есть в потоке, то он содержится между маркером начала текста BT beginning of text и конца ET end of text. PDF может отображать текст или не отображать, в зависимости наличия маркета Tj отобразить текст или маркера TJ отобразить текст с учтом индивидуального символьного позиционирования. Данные маркеры стоят после строки текста или массива строк, как в данном случае. Об этом подробнее позже. Этой информации нам достаточно, чтобы выделить две строки из нашего примера 1. И он окажется прав, но Но вы не находите, что уж очень странные hex коды у данного текста ПАРУС кодируется, как 0. Белеет как 0. 6 0. Очень похоже на то, что есть какая то таблица соответствий, не так лиЧто ж вы опять правы, давайте искать. Попробуем разобраться что к чему. Итак, нас интересуют To. Unicode CMaps, о которых рассказывается в подразделе о получении текста описания формата PDF от Adobe. Давайте поищем их в нашем файле. Я опять смухлюю и предложу читателю заведомо правильный кусочек Расшифруем его CIDInitProc. Set findresource begin. CIDSystem. Infolt lt. Registry Adobe. Ordering UCS. CMap. NameAdobe Identity UCS def. CMap. Type 2 def. F. lt 0. 2 lt 0. B. Ещ бы мы их видели чуть раньше в текстовых строках. Предположим, что мы должны заменить 0. F, взглянем, что скрывает за собой это число. Мы нашли трансформацию одного символа в другой, теперь обратимся к документации и узнаем чуть больше. Преобразование, что находится между beginbfchar и endbfchar, самое простое. Оно ставит в соответствие первому коду другой. Например, в примере выше мы узнали, что 0. П. Но это лишь частный случай работы данного преобразования есть возможность ставить в соответствие одному коду целую строку до 5. Оно работает уже не с отдельными символами, а уже с их диапазонами. Преобразование поддерживает два вариант своей работы lt 0. E lt 0. 02. E, каждое значение из которого преобразуется в значения из промежутка 0. E. Заметили принципF lt 0. Что ж время представить самые интересные куски кода и ссылку на полный исходник function pdf. Нам требуется получить все текстовые данные из файла. После этого действия мы имеем дело только с plain text. По окончанию, возвращаем полученный результат. Есть документы, в которые, к примеру, внедрены русские шрифты, осуществляющие трансформацию из символов английского алфавита в отображение русских букв. Этот код не работает с индивидуальным позиционированием символов. Задача посильная и не сложная, я возлагаю е решение на плечи читателя.