Пишем программу (в 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('
>end;
'+s+'>OutList.Add('
>end; // StyleStucture;
>// конец кода
Пожалуй, это самый тяжелый код в данном манускрипте, но он вроде работает, хотя я вижу в нем по крайней мере две неувязки, но что это, не скажу…
Ну вот с обработкой книги почти закончили, мелкие подробности увидите в исходнике.
Нажимаем пункт меню File – Save as FB2.
И – ничего не получается. Запланированная шутка. Вылезла надпись «Заполнить поля» и фокус перенаправлен на начальную закладку.
Напоминаю FB2 – это не только легкоусвояемый (легкоусваиваемый) текст, но и очень нужный и полезный заголовок книги.
Давайте посмотрим, все таки, что происходит при выборе пункта Save as FB2
>// начало кода
>procedure TForm1.SaveasFB21Click(Sender: TObject);
>begin
>if not BookHaveName then // проверяем, все ли в порядке в заголовке
>begin // если нет, то происходит все то что Вы видели
>PageControl1.ActivePageIndex:= 0;
>ShowMessage('Fill the form.');
>exit;
>end;
>SaveDialog1.FileName:= form1.FB2_file.Text;
>if SaveDialog1.Execute then
>Make_fb2(SaveDialog1.FileName);
>end;
>// конец кода
>Посмотрим на процедуру BookHaveName
>// начало кода
>function BookHaveName: boolean;
>begin
>with Form1 do
>result:= (book_title.Text <> '') and
>(FB2_file.Text <> '') and
>(GenresBox.Count > 0);
>end;
>// конец кода
Ничего особенного в этой функции нет. Единственно из-за чего я ее вытащил, это сказать, что Вы можете и скорее даже будете вынуждены, как-то изменить ее, чтобы контроль заполнения заголовка книги был более разумным.
А я пока вернусь к заполнению заголовка.
В программе Вы видите три закладки Title-info, Document-info и Publish-info. В формате FB2 есть еще кое-что, но я пока это игнорировал. Предоставляю Вам такую возможность. Код Вам в руки…
Итак Title-info
Поле Project ― само заполнится при открытии текстового файла. При желании, Вы можете изменить, имя сохраняемого fb2 файла.