"Пишем программу для создания книг FB2." - читать интересную книгу автора (Карпов Юрий)Создание FB2Наконец добрались. Казалось бы, что проще, бери строку за строкой и вперед… // начало кода with Form1.ListBox1 do for i:= 0 to Count - 1 do // просматриваем текст абзац за абзацем begin S:= Items[i]; // считываем строку Ss:= GetStyle(S, CurStyle); // получаем чистую строку и стиль s:= ''; // подготавливаемся к преобразованию строки if ss lt;gt; '' then for j:= 1 to length(Ss) do begin // просматриваем строку посимвольно case ss[j] of '~': begin // если это концевая сноска S:= S + 'lt;a l: href="#n_'+IntToStr(EndNotes_count)+'" type="note"gt;' +IntToStr(EndNotes_count)+'lt;/agt;'; inc(EndNotes_count); // увеличиваем счетчик сносок end; '^': S:= S + 'amp;#769;'; // ставим ударение else S:= S + ss[j]; // иначе записываем символ в итоговую строку end; // case end; … // тут я пока немножко пропущу … // анализ стилей case CurStyle of // в зависимости от стиля абзаца Norm,Epig,Citat: OutList.Add('lt;pgt;'+S+'lt;/pgt;'); H1..H5: StyleStucture; // Heading Sub: OutList.Add('lt;subtitlegt;'+s+'lt;/subtitlegt;'); // Subtitle // конец кода Давайте рассмотрим все по порядку: Начнем со стихов. В стандарте FB2 используется три тега для работы со стихами, я использую только один стиль "P". Для разделения стихов на строфы я предлагаю использовать пустые строки помеченные стилем "P". // начало кода if (CurStyle lt;gt; oldStyle) then // если предыдущий стиль отличен от текущего begin // а нынешний стиль есть в данном списке, то значит надо начинать нужный блок. case CurStyle of // начало блока Poem: OutList.Add('lt;poemgt;lt;stanzagt;'); Epig: OutList.Add('lt;epigraphgt;'); Citat: OutList.Add('lt;citegt;'); end; // case начало блока end; // конец кода А для обработки стиля используется следующие строки // начало кода case CurStyle of // в зависимости от стиля абзаца Norm,Epig,Citat: OutList.Add('lt;pgt;'+S+'lt;/pgt;'); Poem: begin if S = '' then OutList.Add('lt;/stanzagt;lt;stanzagt;') else OutList.Add('lt;vgt;'+S+'lt;/vgt;'); end; // конец кода В случае Нормальное стиля, Эпиграфа и Цитаты, просто добавляются абзацы, а для стихов еще отслеживается пустая строка… Как видите блоки не завершены. Эту функцию выполняет следующий код. // начало кода if (CurStyle lt;gt; oldStyle) and (CurStyle lt;gt; Auth) then begin case oldStyle of // завершение предыдущего блока Poem: OutList.Add('lt;/stanzagt;lt;/poemgt;'); Epig: OutList.Add('lt;/epigraphgt;'); Citat: OutList.Add('lt;/citegt;'); end; // case завершение предыдущего блока end; // конец кода Но как Вы увидите в исходнике последний программный кусок находится выше предыдущего (и вообще все немного не так), но в данном тексте, мне пришлось расположить их так для последовательного, логичного объяснения, а в программе: сначала проверяется завершенность предыдущих блоков, затем при необходимости начинается другой, а затем обрабатываем текущий стиль. В данном сочинении, я часто буду пользоваться таким приемом, отступлением от порядка следования текста в исходнике, что делать, человеческая логика и машинная не совсем совпадают. Если Вы внимательно следите за процессом, то заметили " and (CurStyle lt;gt; Auth) " в предыдущем кусочке о начале блока, я это дело опустил, что бы не затуманивать описание. Это достаточно забавный код призван выполнить требования формата: // начало цитаты Внутри тэгов lt;poemgt;, lt;citegt; и lt;epigraphgt; возможно указать автора соответственно стихотворения, цитаты или эпиграфа. Для этого служит тэг lt;text-authorgt;. Этот тэг должен стоять в самом конце родительского тэга, то есть непосредственно перед его закрытием. // конец цитаты А теперь как это я сделал. // начало кода Auth: begin OutList.Add('lt;text-authorgt;'+S+'lt;/text-authorgt;'); if oldStyle in [Poem, Epig, Citat] then CurStyle:= oldStyle; // т. е. корректно отработается закрытие родительских блоков end; // конец кода Т.к. естественно я сделаю эту брошюрку с помощью своей программки. Опробуем вышеизложенные методы форматирования на следующем оптимистичном стихотворении. |
|
|