Главная » Статьи » Lazarus |
2. Подготовка и вставка таблиц в текст RTF 1. Предварительные замечанияВ прошлом году я скачал с сайта Журнал "Самиздат" произведения Михаила Харитонова в формате FB2. Как выяснилось практически все файлы содержали ошибки в структуре XML и FB2. Открывать их отказались не только программы чтения, но и редактор fb2edit.exe. Так как я уже пытался работать с форматом FB2 при формировании файловой структуры своей локальной библиотеки на десктопе, то решил "сваять" свой редактор FB2, используя FPC / Lazarus. Постепенно редактор оброс множеством функций и дополнений, и, в конце концов, было решено дополнить возможностью форматированного просмотра текста FB2. В качестве основы был выбран компонент RichMemo, который в ОС Windows построен на базе элемента управления Rich Edit. Компонент RichMemo позволил достаточно просто управлять параметрами шрифтов, выравниванием и метриками абзацев, вставку в текст изображений. Однако некоторые затруднения вызвала необходимость размещения в тексте таблиц и работа с ссылками. Далее описываются некоторые результаты, полученные мной в процессе работы. Все изложенное ниже проверялось только при работе в ОС Windows, т.е. в случае работы с системным элементом Rich Edit. Как известно, элемент Rich Edit работает с текстами в формате RTF (Rich Text Format), поэтому чтобы обеспечить полноценную работу с фрагментами текста необходимо формировать и вставлять эти фрагменты именно в формате RTF. Кроме этого текстовые фрагменты должны иметь кодировку Windows-1251 или кодами в Юникоде. По умолчанию в Lazarus принята кодировка UTF-8, поэтому требуются некоторые усилия для обеспечения правильной кодировки. Для вставки фрагментов в формате RTF дополняем класс TRichMemo следующим helper'ом: type { TRichMemoHelper } TRichMemoHelper = class helper for TRichMemo { TRichMemoHelper } procedure TRichMemoHelper.InsertRTFOverClipBoard(const s: T1251String); Тип строки T1251String предназначен для автоматической перекодировки UTF-8 → Windows-1251. Объявление этого типа имеет следующий вид: type T1251String = Type AnsiString(1251);
2. Подготовка и вставка таблиц в текст RTFДля описания таблиц в документах FB2 используется код XML очень похожий на упрощенное описание таблиц в HTML. Элемент <table> содержит контейнеры для создания строк, которые задаются тегом <tr>. Для этого тега может быть задан атрибут align, определяющий выравнивание содержимого по горизонтали в ячейках строки. Каждая ячейка таблицы в пределах строки задается с помощью тегов <td> или <th>. Для этих тегов могут быть заданы атрибуты:
С тегом <th> создаются ячейки, которые обозначаются как заголовочные. Текстовое содержимое этих ячеек выделяется соответствующим форматированием, например, жирным шрифтом. Приведенный выше XML код определяет таблицу следующего вида:
Теперь рассмотрим, как должен быть сформирован RTF текст, который позволяет вставить в TRichMemo рассмотренную выше таблицу. Следует отметить, что при формировании RTF текста все размеры устанавливаются в твипах (twips) равных одной двадцатой пункта или 1/1440 дюйма, примерно 0,0176 мм. Предполагается, что таблица содержит только текстовые данные, которые отображаются шрифтом одинаковой гарнитуры. Для дополнительного форматирования могут применяться следующие теги:
Приведем с описанием элементы текста с привязкой к исходному XML коду. Более подробно о формате RTF текста версии 1.0 можно, например, здесь. {\rtf1\ansi\ansicpg1251 — заголовок RTF v.1.0, набор символов ANSI и кодовая страница Windows 1251; Полученная строка вставляется в необходимое место с помощью описанного выше метода InsertRTFOverClipBoard. Предварительно должен быть вставлен небольшой фрагмент текста (достаточно одного пробела), для которого выставляются все необходимые атрибуты текста. Пример фрагмента кода для вставки сформированной строки: //установка параметров форматирования для таблицы //передаем через clipboard RTF, сформированный buf — строка ранее описанного типа T1251String
3. Вставка ссылки в текст RTFКомпонент RichMemo позволяет размещать в тексте гиперссылки. Для этого имеется следующий метод: procedure TCustomRichMemo.SetLink(TextStart, TextLength: Integer; AIsLink: Boolean; const ALinkRef: String = ''); virtual; где TextStart, TextLength — определяют позицию в тексте, которой назначается/удаляется гиперссылка; AIsLink — равен true при установке гиперссылка, и false – при удалении; ALinkRef — текст гиперссылки. Событие выбора пользователем гиперссылки обрабатывается в обработчике OnLinkAction, который должен быть назначен на метод следующего типа: TLinkActionEvent = procedure (Sender: TObject; ALinkAction: TLinkAction; const info: TLinkMouseInfo; LinkStart, LinkLen: Integer) of object; где ALinkAction — тип события, единственное значение laClick; info — запись с двумя полями: info.Button — значения mbLeft или mbRight; info.LinkRef — текст гиперссылка; LinkStart, LinkLen — позиция гиперссылки в тексте. Тестирование работы с гиперссылками в компоненте RichMemo показало, что при назначении текста гиперссылки через параметр ALinkRef в методе SetLink, в обработчике OnLinkAction значение поля info.LinkRef всегда равно строковому значению фрагмента текста, определяемого параметрами TextStart и TextLength в методе SetLink. Анализ кода реализации RichMemo для Windows показал, что значение параметра ALinkRef вообще не используется. Признак гиперссылки производится лишь установкой флага CFE_LINK для фрагмента текста, определяемого параметрами TextStart и TextLength в методе SetLink. Как указано на сайте Microsoft, для определения гиперссылки с понятным именем (Friendly Name Hyperlinks) необходимо вставить соответствующий текст RTF: {\rtf1\ansi\ansicpg1251{\field{\*\fldinst{ HYPERLINK "http://www.msn.com"}}{\fldrslt{ MSN}}}}, где http://www.msn.com — адрес гиперссылки; MSN — отображаемое в тексте имя гиперссылки. Пример фрагмента кода для вставки гиперссылки c адресом hrefAddr и отображаемым текстом hrefText: const cRTFLinkTextTemplate:string = st := UTF8Length(FRichMemo.Text); //позиция вставки гиперссылки - здесь конец текста buf := Format(pRTFLinkText, [hrefAddr, hrefText]); //формирование текста в RTF FRichMemo.InsertOverClipBoard(buf); //передача RTF через clipboard Отображаемый текст hrefText может содержать теги форматирования, аналогично ранее описанных для текстовых данных таблицы.
| ||||||||||||||||
Просмотров: 627 | |
Всего комментариев: 0 | |