Система вёрстки документов. Часть 1 — Основа
Вступление
В этом году я закончил бакалавриат по специальности «Программная инженерия» и соответственно защитил диплом. По моему скромному мнению у меня получилась довольно интересная программа, о которой я и хотел бы рассказать в этой и последующих статьях.
Бэкстори
В конце второго курса всю нашу группу гоняли на предмет выбора темы диплома. Стоит упомянуть, что в моём университете этот процесс обычно выглядит так — ты подходишь к преподавателю у которого есть список тем и выбираешь понравившуюся. Такие темы обычно звучат так: «Модуль расписание для студентов кафедры АСОИУ», в общем, какое-то приложение для нужд студентов или преподавателей, будь то расписание, автоматизация подачи заявок на повышенную стипендию и так далее.
Мне такой расклад не очень нравился, по причине того, что на диплом уйдёт очень много времени и я хотел, чтобы такой длительный проект был звёздочкой в моём портфолио, а в идеале был бы таким проектом, которым я бы занимался и после защиты оного. Мне хотелось взять что-то поинтереснее.
В то время я готовился к экзаменам и составлял портфолио для поступления в магистратуру. Для подготовки я всегда делал себе записки с выжимками из книг и лекций, изначально как и все в MS Word, однако в какой-то момент я понял сколько же времени уходили на стилизацию этих документов, при том что разделы и элементы всегда типовые. Ровно в то же время я писал пояснительную записку для курсового проекта, где по какой-то причине ворд никак не хотел делать мне нормально содержание, дополнительное раздражение вызывало то, что я не могу просто скопировать типовой блок документа (раздел с подразделом внутри и так далее) и заменить текст — ведь начнётся суматоха с отступами и подобные вещи.
Тогда я вспомнил, что когда-то пытался пользоваться LaTeX — это такой язык разметки для создания документов. В шаблоне описаны стили отображения элементов документа, а ты в свою очередь вводишь неотформатированный текст из которого потом собираться красивая PDFка.
Я решил сделать своё портфолио в LaTeX, результат был приятным, однако когда я сел писать пояснительную записку к курсовой работе в нём возникли проблемы. Не хватало готового шаблона, к тому же пришлось бы изучать этот инструмент от и до, чтобы написать комплексный большой документ.
Тогда я и придумал свою тему — сделать свой язык разметки для создания документов. Не буду писать тут о том, сколько я бился с кафедрой, чтобы всё-таки оставить свою тему и не брать другую у них.
Сразу было понятно, что подготовку стоит начать с изучения PDF-формата.
Сразу стоит посмотреть как выглядят PDF-файлы изнутри, что кроется за красивым текстом и картинками:
Декомпрессированный PDF-файл
В этом файле мы видим объявление страницы, текста, шрифта — всю информацию необходимую для отрисовки документа. Со стороны может показаться, что это какой-то очень странный язык программирования, что на самом деле не так далеко от правды.
PDF. Объекты
Большая часть PDFки состоит из объектов, у которых есть свои типы: строка, массив, integer и real цифры, булевое значения, ассоциативный массив, поток, нулевой объект.
Пример объекта:
15 0 obj
<<
/Type /Font
/Subtype /CIDFontType2
/BaseFont /BYAZWPA+Times-Roman
/CIDToGIDMap /Identity
/CIDSystemInfo
<<
/Ordering (Identity)
/Registry (Adobe)
/Supplement 0
>>
/FontDescriptor 10 0 R
/DW 250
/W [ 20 100 [500] 3 [250] ]
>>
endobj
Это объект 15, первая цифра это имя объекта, вторая цифра в 99% является нулём, поэтому не будем заострять на этом внимание. Ключевые слова obj и endobj говорят о начале и конце объявления объекта. Далее мы видим »<<" и в конце ">>» — что означает, что тип объекта — ассоциативный массив. Соответственно мы видим ключи и их значения, например ключ «Type» имеет значение «Font», из чего мы делаем вывод, что данный объект описывает некий шрифт, а именно как видно из значения ключа «BaseFont» — TimesNewRoman.
Также мы видим, что значение ключа «W» — это массив, они заключены в квадратные скобки и значения в них просто идут друг за другом.
Заметим, что странное значение ключа «FontDescriptor» — это ссылка на другой объект, где 10 — это его имя, 0 — это то самое странное число. Значит, где-то сверху мы сможем найти строку »10 0 obj» с описанием объекта на который мы и ссылаемся.
А значение ключа «CIDSystemInfo» в свою очередь является ассоциативным массивом.
PDF. Структура
PDF-файлы имеют строгую структуру.
Структура PDF-файла
Сначала идёт заголовок — информация о версии PDF.
%PDF-1.6
Далее мы увидим последовательность объектов, являющихся контентом (заполнением) документа, т.е. то что мы хотим увидеть — это тело документа. Пример объекта мы рассмотрели выше.
Таблица перекрёстных ссылок — хранит информацию о нахождении тех или иных объектов в файле и как до них добраться.
xref
0 18
0000000000 65535 f
0000000009 00000 n
0000000058 00000 n
0000000117 00000 n
0000000388 00000 n
0000000650 00000 n
0000000690 00000 n
0000003792 00000 n
0000838313 00000 n
0001680550 00000 n
0001680774 00000 n
0001681000 00000 n
0001681542 00000 n
0001682084 00000 n
0001687861 00000 n
0001688249 00000 n
0001688641 00000 n
0001688787 00000 n
Объявление начинается с ключевого слова «xref». Первое число 0 ссылается на нулевой объект (его вы не найдёте в своём файле, это специальный узел дерева документа) после которого идёт число строк таблицы (обычно оно равно количеству объектов в PDF-файле). Далее каждая строка хранит адрес нахождения объекта. Первая строка заканчивается буквой f и ссылается на первый узел дерева документа, далее всё, что кончается буквой n — адреса наших объектов (сколько байт с начала файла нужно пройти, чтобы дойти до нужного объекта).
Трейлер — позволяет быстро определить где находиться таблица перекрёстных ссылок.
trailer
<<
/Size 18
/Root 1 0 R
>>
startxref
1688934
%%EOF
Тут мы снова видим количество объектов в документе, а также количество байт которое нужно пройти с начала документа, чтобы дойти до таблицы перекрёстных ссылок. Далее следует определение конца файла.
В следующей части мы попробуем собственноручно создать «Hello, world» PDFку и окунёмся глубже в её синтаксис.