Пишем программу (в Delphi) для создания книг FB2
- « Предыдущая стр.
- Следующая стр. »
Введение
В начале было слово, и слово было 2 байта…
Автор мне неизвестен.
Все началось с покупки электронной книжки LBook eReader V3.
Затем я убедился, что книги, лучше всего читаются в формате FB2.
Потом мне захотелось оцифровать книги моего любимого писателя Кальмана Миксата, и тут я увидел, что все не так просто…
Да я в этой «тусовке» недавно и возможно чёто не понимаю, но все свои проблемы я привык решать программным путем.
Состряпал программку, конечно еще сырую, а потом вспомнил опыт Линуса Торвальдса и подумал:
― А, кину я исходник в рунет, и может добрые люди выкормят, вырастят моего ребенка и выведут в люди.
Вы можете спросить, а чего же ты сам это не сделаешь? Во-первых, меня ждут другие «великие дела» , во-вторых, я уверен, что коллективным разумом, можно сделать больше и быстрее…
Писал я в своем любимом Delphi (Delphi 6) ― но думаю это не принципиально, перевести можно в любой язык.
Это не учебник Delphi и основы, я рассказывать не собираюсь, но постараюсь расписать как можно подробней.
В программе используются только стандартные компоненты Дельфи.
Начинаем
План работы:
• Берем текстовый файл
• Присваиваем строчкам стили
• Делаем файл FB2.
Общие принципы программы.
Содержание книги будет хранится в ListBox1.
Каждая строчка в ListBox1 будет содержать абзац текста и будет начинаться с идентификатора стиля абзаца, например:
// начало примера.
H1 | Кальман Миксат. ЧЕРНЫЙ ГОРОД
H2 | ЧАСТЬ ПЕРВАЯ
H3 | ГЛАВА ПЕРВАЯ.
S| В которой содержатся сведения и подробности, весьма важные для читателя
N| Пал Гёргей был самым примечательным вице-губернатором Спеша во времена Тёкёли
// конец примера.
Символ | отделяет информацию о стиле от строки текста. Теперь надо объяснить, что означают эти буковки.
С H1 по H5: заголовки разных уровней структуры книги (части, главы, разделы и т. п.), я посчитал, что 5 уровней более чем достаточно, мне пока требовалось только три.
S: Subtitle – подзаголовок.
N: Normal – обычный абзац.
Еще могут использоваться стили:
E: Epigraph – эпиграф
T: Text-author – автор цитаты / эпиграфа
P: Poem – стихи
-: None строка будет игнорироваться при записи FB2 файла.
Если потребуется Вы добавите еще…
Читаем текстовый файл
При чтении текстового файла, к каждой строчке прибавляется начало ' N| ' т. к. форматирование еще не сделано и все строки одинаково обычны.
>// начало кода
>procedure LoadTXT(FName: string);
>var
>L: TStringList;
>i, j: integer;
>s, ss: string;
>begin
>L:= TStringList.Create; // создаем временный список
>L.LoadFromFile(fname); // читаем из файла // можно сделать грамотнее с помощью try
>for i:= 0 to L.Count – 1 do// просматриваем текст
>begin
>s:= ''; ss:= L[i];
>for j:= 1 to length(Ss) do
>begin // просматриваем строку
>case ss[j] of
>'<': S:= S + '<'; // знак < вызывает сбой в читалке. т. к. она думает что дальше следует тэг
>'>': S:= S + '>'; // заменяем, на всякий случай
>'^': S:= S + '^'; // этот символ будет использован в служебных целях
>'~': S:= S + '~'; // – // –
>'&': S:= S + '&';
>else S:= S + ss[j]; // иначе, претензий нет, символ добавляем к строке
>end; // case
>end; // обработка строки завершена
>L[i]:= ' N| ' + S; // в начало каждой строки вводим указатель стиля Normal
>end; // обработка текста завершена
>Form1.ListBox1.Items.Assign(L); // сбрасываем список в ListBox
>L.Free; // удаляем временный список
>end;
>// конец кода
Если файл считан, теперь мы можем его форматировать.
Просматриваем текст книги, выделяем нужную строку, выбираем необходимый стиль и нажимаем кнопку
[>]
При этом вызывается процедура >ChangeStyle(TmyStyle(RG.itemindex))
;
Как параметр она получает стиль из радио – списка RG.
К сожалению это все делать надо ручками. Конечно, возможна некая автоматизация, но пока идет речь об упрощенной программе…
Процедура считывает выделенную строку из списка ListBox1, удаляет сведения о типе и записывает строку на старое место с новым стилем.
>// начало кода
>procedure ChangeStyle(LStyle: TmyStyle);
>var
>n, curIndex: integer;
>S: string;
>begin
>with Form1.ListBox1 do
>begin
>curIndex:= ItemIndex; // читаем текущий индекс в списке ListBox
>if curIndex = –1 then exit; // если ничего не выделено выходим
>S:= Items[curIndex]; // считываем текущую строку