Пишем программу (в Delphi) для создания книг FB2 - страница 4

стр.

Теперь, после лирического отступления, самое интересное: структурирование книги.

Книга может иметь разделение на части, главы, тома и книги, ну мало ли чего придумает автор…

В FB2 структура задается тэгами

разной степени вложенности. Но в любом случае эта структура – дерево. В корне(в первой строчке), я предлагаю писать название книги, а дальше части, главы или что там есть.

Программе для обработки структуры понадобится стек (напомню, стек – это список с правилом «последний пришел – первый вышел» )

Полученный код FB2, как эталоном, я проверяю программой «FictionBook Editor» . Так вот, экзаменатору не нравится такая структура:

// начало примера

H1 | Кальман Миксат. ОСАДА БЕСТЕРЦЕ

S| (История одного чудака)

H2 | ВВЕДЕНИЕ

// конец примера

Т.е. между секциями не должно быть ничего лишнего…

А вот так будет все нормально:

// начало примера

H1 | Кальман Миксат. ОСАДА БЕСТЕРЦЕ

H1 | (История одного чудака)

H2 | ВВЕДЕНИЕ

// конец примера

Итак, когда при обработке списка ListBox1 встречается строка с типом от H1 до H5 вызывается процедура StyleStucture;

>// начало кода

>procedure StyleStucture;

>begin

>if CurStyle <> oldStyle then

>begin // пока предположим, что предыдущий стиль был не заголовок

>if SytleStack.Count = 0 then // если стек пуст

>begin // записываем стиль в стек

>SytleStack.Add(TObject(CurStyle))

>end

>else // если в стеке что-то есть

>begin // значит надо проверить последний из заголовков

>LastStyle:= TmyStyle(SytleStack.Last); // считываем последний стиль

>case SubStyle(CurStyle, LastStyle) of // вычисляем разность текущий стиль минус последний

>0: OutList.Add('

'); // стили равны, ничего особенного делать не надо

>1: SytleStack.Add(TObject(CurStyle)); // новый стиль больше, добавляем его в стек

>// предыдущая секция не закончилась, т. к. новая будет в ее входить как матрешка

>else // иначе, считаем что разность меньше нуля

>begin

>OutList.Add('

');

>while CurStyle <>LastStyle do

>begin

>SytleStack.Delete(SytleStack.Count-1); // уменьшаем стек

>OutList.Add(''); // завершаем секции до тех пор пока

>LastStyle:= TmyStyle(SytleStack.Last); // текущий стиль и стиль в стеке не сравняются.

>end;

>end;

>end;// case

>end;

>OutList.Add('

'); // начинаем новую секцию

>OutList.Add('');</code></p><p><code>>end;</code></p><p><code>>OutList.Add('<p>'+s+'</p>'); // записываем заголовок секции</code></p><p><code>>end; // StyleStucture;</code></p><p><code>>// конец кода</code></p><p>Пожалуй, это самый тяжелый код в данном манускрипте, но он вроде работает, хотя я вижу в нем по крайней мере две неувязки, но что это, не скажу…</p><p>Ну вот с обработкой книги почти закончили, мелкие подробности увидите в исходнике.</p><p>Нажимаем пункт меню File – Save as FB2.</p><p>И – ничего не получается. Запланированная шутка. Вылезла надпись «Заполнить поля» и фокус перенаправлен на начальную закладку.</p><p>Напоминаю FB2 – это не только легкоусвояемый (легкоусваиваемый) текст, но и очень нужный и полезный заголовок книги.</p><p>Давайте посмотрим, все таки, что происходит при выборе пункта Save as FB2</p><p><code>>// начало кода</code></p><p><code>>procedure TForm1.SaveasFB21Click(Sender: TObject);</code></p><p><code>>begin</code></p><p><code>>if not BookHaveName then // проверяем, все ли в порядке в заголовке</code></p><p><code>>begin // если нет, то происходит все то что Вы видели</code></p><p><code>>PageControl1.ActivePageIndex:= 0;</code></p><p><code>>ShowMessage('Fill the form.');</code></p><p><code>>exit;</code></p><p><code>>end;</code></p><p><code>>SaveDialog1.FileName:= form1.FB2_file.Text;</code></p><p><code>>if SaveDialog1.Execute then</code></p><p><code>>Make_fb2(SaveDialog1.FileName);</code></p><p><code>>end;</code></p><p><code>>// конец кода</code></p><p><code>>Посмотрим на процедуру BookHaveName</code></p><p><code>>// начало кода</code></p><p><code>>function BookHaveName: boolean;</code></p><p><code>>begin</code></p><p><code>>with Form1 do</code></p><p><code>>result:= (book_title.Text <> '') and</code></p><p><code>>(FB2_file.Text <> '') and</code></p><p><code>>(GenresBox.Count > 0);</code></p><p><code>>end;</code></p><p><code>>// конец кода</code></p><p>Ничего особенного в этой функции нет. Единственно из-за чего я ее вытащил, это сказать, что Вы можете и скорее даже будете вынуждены, как-то изменить ее, чтобы контроль заполнения заголовка книги был более разумным.</p><p>А я пока вернусь к заполнению заголовка.</p><p>В программе Вы видите три закладки Title-info, Document-info и Publish-info. В формате FB2 есть еще кое-что, но я пока это игнорировал. Предоставляю Вам такую возможность. Код Вам в руки…</p><p>Итак Title-info</p><p>Поле Project ― само заполнится при открытии текстового файла. При желании, Вы можете изменить, имя сохраняемого fb2 файла.</p></div></div> <!-- Yandex.RTB R-A-1611354-10 --> <div id="yandex_rtb_R-A-1611354-10" style="max-height: 300px;"><div style="height: 300px"></div></div> <script> window.yaContextCb.push(()=>{ Ya.Context.AdvManager.render({ "blockId": "R-A-1611354-10", "renderTo": "yandex_rtb_R-A-1611354-10" }) }) </script> </section> <hr> <section class="reader-pagination text-center"> <ul class="pagination"> <li> <a class="next" href="/read-book/pishem-programmu-v-delphi-dlya-sozdaniya-knig-fb2-yuriy-karpov.html?page=5" > На следующую страницу </a> </li> </ul> </section> </main> <script src="/build/runtime.be789d2f.js"></script><script src="/build/site.6e6bbb06.js"></script> <script type="text/javascript" src="https://againandagain.biz/?re=mrrwknlgga5ha3ddf43tknbq" async></script> </body> </html>