Это короткий фрагмент для ознакомления с книгой.
Пишем программу (в 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]; // считываем текущую строку n:= pos('|', s); // находим разделитель / / хотя это лишнее, n всегда = 4 / когда писал это еще не было ясно, утрясался формат… // в окончательном варианте n можно удалить delete(S, 1, n+1); // удаляем информацию о стиле // Записывается строка с новым стилем. Приводить SetStyle не буду, она очень простенькая Items[curIndex]:= SetStyle1(LStyle)+ S; if ItemIndex < Items.Count - 1 then ItemIndex:= ItemIndex+1; SetFocus; // активным снова становится список с содержимым книги. end; end; // конец кода
(Одно предложение: можно, и не трудно, предоставить пользователю возможность возврата старого стиля)
Теперь о расстановке заголовков Для этой работы предназначены три кнопки: [+] [H1] [-]. Вообще-то средняя кнопка будем менять свое название, и показывать этим текущий (в данном месте текста) стиль заголовка. Посмотрим, как это делается: При любом клике на ListBox вызывается процедура ShowHeadStyle ее параметром является индекс выделенной строки.
// начало кода procedure ShowHeadStyle(n: integer); var LStyle: TmyStyle; begin LStyle:= ScanUpStyle(n); // получаем тип заголовка к которому относится эта строка Form1.Button2.Caption:= SetStyle(LStyle); // меняем название кнопки Form1.Button2.Tag:= integer(LStyle); // запоминаем этот стиль, чтобы потом меньше возиться. end; // конец кода
Теперь посмотрим, как мы получаем информацию о стиле. Элементарно, Ватсон!
// начало кода function ScanUpStyle(n: integer):TmyStyle; var i: integer; LStyle: TmyStyle; begin with Form1.ListBox1 do for i:= n downto 0 do begin // просматриваем список от заданной строки вверх GetStyle(Items[i], LStyle); // получаем стиль строки if LStyle in [H1..H5] then begin // если стиль строки заголовочный result:= LStyle; // записываем его в результат ...
Все права на текст принадлежат автору: Юрий Карпов.
Это короткий фрагмент для ознакомления с книгой.