Форум программистов, компьютерный форум, киберфорум
diadiavova
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Об XML-фильтрах OpenOffice. Часть 3-я.

Запись от diadiavova размещена 10.06.2015 в 12:25
Показов 2594 Комментарии 0
Метки libreoffice, openoffice, xslt

  1. Решение проблемы разделения на строки.
  2. Демонстрация работы подсветки синтаксиса кода
Решение проблемы разделения на строки.

Коль скоро мы начали с определения цвета, возьмемся за раскрашивание текста. То есть целью будет получение текста документа, раскрашенного с помощью BB-кодов. Добавим в преобразование следующую функцию, которая будет оборачивать переданный узел тегами COLOR
XML
1
2
3
4
5
  <xsl:function name="my:colorize">
    <xsl:param name="node"/>
    <xsl:variable name="color" select="my:style-property-value($node, 'fo:color')"/>
    <xsl:value-of select="concat('[COLOR=&quot;', $color, '&quot;]', $node, '[/COLOR]')"/>
  </xsl:function>
Кроме того, нам понадобится шаблон, обрабатывающий текстовые узлы, а так же отредактируем шаблон, с которого начинается обработка документа
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  <xsl:template match="/">
    <root>
      <xsl:text disable-output-escaping="yes">
&lt;![CDATA[
</xsl:text>
 
      <xsl:apply-templates select="//office:body"/>  
 
      <xsl:text disable-output-escaping="yes">
]]&gt;
</xsl:text>
    </root>
  </xsl:template>
 
 
  <xsl:template match="text()">
    <xsl:value-of select="my:colorize(.)" disable-output-escaping="yes"/>
  </xsl:template>
 
<xsl:template match="office:binary-data"/>
Кроме того добавил <xsl:template match="office:binary-data"/>, чтобы исключить бинарные данные из выходного потока.

Вот результат
XML
1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
<root>
<![CDATA[
[COLOR="#2e74b5"]Заголовок 1[/COLOR]Обычный текст[COLOR="#2e74b5"]Заголовок 2[/COLOR][COLOR="#1f4d78"]Заголовок 3[/COLOR][COLOR="#2e74b5"]Заголовок 4[/COLOR][COLOR="#2e74b5"]Заголовок 5[/COLOR][COLOR="#1f4d78"]Заголовок 6[/COLOR][COLOR="#1f4d78"]Заголовок 7[/COLOR]Название[COLOR="#5a5a5a"]Подзаголовок[/COLOR][COLOR="#5b9bd5"]Сильное выделение[/COLOR]Строгий[COLOR="#404040"]Цитата 2[/COLOR][COLOR="#5a5a5a"]Слабая ссылка[/COLOR][COLOR="#5b9bd5"]Сильная ссылка[/COLOR]Название книгиАбзац списка.ЖирныйКурисивПодчеркнутыйПеречекнутыйХНижний индексХВерхний идексКрупный шрифт 72Мелкий шрифт 8Левое выравниваниеВыравнивание по центруПравое выравниваниеПервый пункт маркированного спискаВторой пункт маркированного спискаПервый пункт нумерованного спискаПункт 1.a;alfjasdf; lj l ;l lj ;lk lkj;lkj l sdls dfslkj as;lПункт 1.b b xj 'nj pf [eqyz&amp;Второй пункт нумерованного списка[COLOR="#ff0000"]Текст красного цвета[/COLOR][COLOR="#00b0f0"]Текст синего цвета[/COLOR]Выделение желтым/*Далее таблица*/1.11.21.31.41.22.22.32.43.13.23.33.4[COLOR="#0563c1"]Ссылка на гуголь[/COLOR]/*Далее картинка*/ЗакладкаТекст с отступом 2 смСсылка на сноску1Сноска на странице.
]]>
</root>
Если текстовые данные просто вставить в пост как цитату, получится вот что
Заголовок 1Обычный текстЗаголовок 2Заголовок 3Заголовок 4Заголовок 5Заголовок 6Заголовок 7НазваниеПодзаголовокСильное выделениеСтрогийЦитата 2Слабая ссылкаСильная ссылкаНазвание книгиАбзац списка.ЖирныйКурисивПодчеркнутыйПеречекн утыйХНижний индексХВерхний идексКрупный шрифт 72Мелкий шрифт 8Левое выравниваниеВыравнивание по центруПравое выравниваниеПервый пункт маркированного спискаВторой пункт маркированного спискаПервый пункт нумерованного спискаПункт 1.a;alfjasdf; lj l ;l lj ;lk lkj;lkj l sdls dfslkj as;lПункт 1.b b xj 'nj pf [eqyz&amp;Второй пункт нумерованного спискаТекст красного цветаТекст синего цветаВыделение желтым/*Далее таблица*/1.11.21.31.41.22.22.32.43.13.23.33.4Ссылка на гуголь/*Далее картинка*/ЗакладкаТекст с отступом 2 смСсылка на сноску1Сноска на странице.
Приятно, конечно, что все раскрасилось как в оригинальном документе, но там вроде как текст многострочным был. А это еще что такое? Так здесь еще строки отрезаются по ширине страницы, а в коде все вообще в одну строку сложено.

Если взглянуть на фрагменты кода с текстом, которые мы уже рассмотрели ранее, то можно заметить, что среди форматирующих элементов (тех, которые имеют ссылку на стиль) на верхнем уровне оказывается либо text:p (для обычного текста) либо text:h (для заголовков). Нетрудно догадаться, что назначение этих элементов примерно такое же, как у элементов p и h1-h6 в HTML. То есть иными словами, мы видим, что любой текст "упакован" в блочный элемент, внутри которого дополнительно могут находиться инлайновые форматирующие элементы. Конечно, это несколько упрощенный взгляд, но если принять во внимание только это обстоятельство, можно получить гораздо более адекватный результат.
Добавим в преобразование такой шаблон
XML
1
2
3
4
5
  <xsl:template match="text:h|text:p">
    <xsl:apply-templates/>
        <xsl:text>
  </xsl:text>
  </xsl:template>
И получим куда более удовлетворительный результат.
Кликните здесь для просмотра всего текста
Заголовок 1
Обычный текст
Заголовок 2
Заголовок 3
Заголовок 4

Заголовок 5
Заголовок 6
Заголовок 7
Название
Подзаголовок
Сильное выделение
Строгий
Цитата 2
Слабая ссылка
Сильная ссылка

Название книги
Абзац списка.
Жирный
Курисив
Подчеркнутый
Перечекнутый
ХНижний индекс
ХВерхний идекс
Крупный шрифт 72
Мелкий шрифт 8
Левое выравнивание
Выравнивание по центру
Правое выравнивание
Первый пункт маркированного списка
Второй пункт маркированного списка

Первый пункт нумерованного списка
Пункт 1.a;alfjasdf; lj l ;l lj ;lk lkj;lkj l sdls dfslkj as;l
Пункт 1.b b xj 'nj pf [eqyz&amp;
Второй пункт нумерованного списка

Текст красного цвета
Текст синего цвета
Выделение желтым
/*Далее таблица*/
1.1
1.2
1.3
1.4
1.2
2.2
2.3
2.4
3.1
3.2
3.3
3.4

Ссылка на гуголь

/*Далее картинка*/

Закладка
Текст с отступом 2 см
Ссылка на сноску1Сноска на странице
.
Следует обратить внимание еще на пару обстоятельств. Все текстовые узлы в документе имеют нормализованную форму. То есть там нет текстов, которые содержат более одного пробела подряд или переходы на новые строки. Однако в документе такие места есть, поэтому интересно посмотреть, как это решается в коде документа. Вот так выглядит код элемента с разрывом строки
XML
1
<text:span text:style-name="T16">1.a;alfjasdf; lj l ;l lj ;lk <text:line-break/>lkj;lkj l sdls dfslkj as;l</text:span>
Здесь элемент text:line-break по сути выполняет ту же роль, что и элемент br в HTML. Если кто не в курсе, то с клавиатуры это набирается путем ввода сочетания Shift+Enter. В этом случае новый абзац не создается, а просто обрывается строка. Другой случай - несколько пробелов подряд. В документе это тоже имеется, но приведу более чистый код
XML
1
<text:p text:style-name="P8">Текст до десяти пробелов <text:s text:c="9"/>Текст после десяти пробелов</text:p>
Думаю, пояснения не нужны. Добавляем еще два шаблона
XML
1
2
3
4
5
6
7
8
9
[noparse]
  <xsl:template match="text:s">
  <xsl:value-of select="for $s in (1 to @text:c) return ' '"/>
    </xsl:template>
  <xsl:template match="text:line-break">
        <xsl:text>
  </xsl:text>
  </xsl:template>
[/noparse]
Вот что имеем теперь
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<?xml version="1.0" encoding="UTF-8"?>
<root>
<![CDATA[
[COLOR="#2e74b5"]Заголовок 1[/COLOR]
Обычный текст
[COLOR="#2e74b5"]Заголовок 2[/COLOR]
[COLOR="#1f4d78"]Заголовок 3[/COLOR]
[COLOR="#2e74b5"]Заголовок 4[/COLOR]
 
[COLOR="#2e74b5"]Заголовок 5[/COLOR]
[COLOR="#1f4d78"]Заголовок 6[/COLOR]
[COLOR="#1f4d78"]Заголовок 7[/COLOR]
Название
[COLOR="#5a5a5a"]Подзаголовок[/COLOR]
[COLOR="#5b9bd5"]Сильное выделение[/COLOR]
Строгий
[COLOR="#404040"]Цитата 2[/COLOR]
[COLOR="#5a5a5a"]Слабая ссылка[/COLOR]
[COLOR="#5b9bd5"]Сильная ссылка[/COLOR]
 
Название книги
Абзац списка.
Жирный
Курисив
Подчеркнутый
Перечекнутый
ХНижний индекс
ХВерхний идекс
Крупный шрифт 72
Мелкий шрифт 8
Левое выравнивание
Выравнивание по центру
Правое выравнивание
Первый пункт маркированного списка
Второй пункт маркированного списка
 
Первый пункт                                                                                                           нумерованного списка
Пункт 1.a;alfjasdf; lj l ;l lj ;lk 
lkj;lkj l sdls dfslkj as;l
Пункт 1.b b xj 'nj pf [eqyz&amp;
Второй пункт нумерованного списка
Текст до десяти пробелов                  Текст после десяти пробелов
[COLOR="#ff0000"]Текст красного цвета[/COLOR]
[COLOR="#00b0f0"]Текст синего цвета[/COLOR]
Выделение желтым
/*Далее таблица*/
1.1
1.2
1.3
1.4
1.2
2.2
2.3
2.4
3.1
3.2
3.3
3.4
 
[COLOR="#0563c1"]Ссылка на гуголь[/COLOR]
 
/*Далее картинка*/
 
Закладка
Текст с отступом 2 см
Ссылка на сноску1Сноска на странице
.
 
 
]]>
</root>

На самом деле дело не ограничивается только именами элементов. Конечно на способ отображения влияет и стиль и контекст. Если говорить о стилях, то у них есть такой атрибут, как style:family. Если он имеет значение paragraph, то элементы, к которым этот стиль относится видимо и будут блочными. Хотя, как видно даже из приведенного примера элементы такого типа вовсе не всегда должны обрабатываться одинаково. Например содержимое ячейки таблицы тоже включает text:p, но если мы будем каждую ячейку на новой строке размещать, то таблицы в BB-кодах уже не получится. Но это я уже вперед забежал. Пока нам достаточно того, что уже сделано.

Демонстрация работы подсветки синтаксиса кода

Ну, о чем-то реально полезном пока говорить рановато, но то, что мы уже сделали вполне можно посмотреть в работе. На данный момент наше преобразование имеет вид как во вложении (ColorizeTextOOFilter.zip).
Можно сохранить его в папке для фильтров и в дальнейшем использовать для тестов, предварительно добавив как фильтр в программу Writer. В Visual Studio имеется одна интересная особенность: когда из редактора кода копируется код, то в буфере обмена он сохраняется не только как текст, но и в формате RTF. Таким образом, когда он вставляется в программу, поддерживающую этот формат, то сохраняется подсветка синтаксиса. "Офисные" программы RTF поддерживают, а нам как раз интересно посмотреть на подсветку синтаксиса. Таким образом я скопирую часть кода нашего преобразования из студии, вставлю код в поле редактора и сохраню с помощью нашего фильтра.
Результат у меня получился вот такой
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<root>
<![CDATA[
   [COLOR="#0000ff"]<[/COLOR][COLOR="#2b91af"]xsl:template[/COLOR][COLOR="#0000ff"] [/COLOR][COLOR="#ff0000"]match[/COLOR][COLOR="#0000ff"]=[/COLOR][COLOR="#000000"]"[/COLOR][COLOR="#0000ff"]/[/COLOR][COLOR="#000000"]"[/COLOR][COLOR="#0000ff"]>[/COLOR]
       [COLOR="#0000ff"]<[/COLOR][COLOR="#a31515"]root[/COLOR][COLOR="#0000ff"]>[/COLOR]
           [COLOR="#0000ff"]<[/COLOR][COLOR="#2b91af"]xsl:text[/COLOR][COLOR="#0000ff"] [/COLOR][COLOR="#ff0000"]disable-output-escaping[/COLOR][COLOR="#0000ff"]=[/COLOR][COLOR="#000000"]"[/COLOR][COLOR="#0000ff"]yes[/COLOR][COLOR="#000000"]"[/COLOR][COLOR="#0000ff"]>[/COLOR]
[COLOR="#ff0000"]&lt;[/COLOR][COLOR="#000000"]![CDATA[[/COLOR]
[COLOR="#0000ff"]</[/COLOR][COLOR="#2b91af"]xsl:text[/COLOR][COLOR="#0000ff"]>[/COLOR]
 
           [COLOR="#0000ff"]<[/COLOR][COLOR="#2b91af"]xsl:apply-templates[/COLOR][COLOR="#0000ff"] [/COLOR][COLOR="#ff0000"]select[/COLOR][COLOR="#0000ff"]=[/COLOR][COLOR="#000000"]"[/COLOR][COLOR="#0000ff"]//office:body[/COLOR][COLOR="#000000"]"[/COLOR][COLOR="#0000ff"]/> [/COLOR]         
 
           [COLOR="#0000ff"]<[/COLOR][COLOR="#2b91af"]xsl:text[/COLOR][COLOR="#0000ff"] [/COLOR][COLOR="#ff0000"]disable-output-escaping[/COLOR][COLOR="#0000ff"]=[/COLOR][COLOR="#000000"]"[/COLOR][COLOR="#0000ff"]yes[/COLOR][COLOR="#000000"]"[/COLOR][COLOR="#0000ff"]>[/COLOR]
[COLOR="#000000"]]][/COLOR][COLOR="#ff0000"]&gt;[/COLOR]
[COLOR="#0000ff"]</[/COLOR][COLOR="#2b91af"]xsl:text[/COLOR][COLOR="#0000ff"]>[/COLOR]
       [COLOR="#0000ff"]</[/COLOR][COLOR="#a31515"]root[/COLOR][COLOR="#0000ff"]>[/COLOR]
   [COLOR="#0000ff"]</[/COLOR][COLOR="#2b91af"]xsl:template[/COLOR][COLOR="#0000ff"]>[/COLOR]
 
 
]]>
</root>
А вот как это выглядит после обработки BB-кодов
<xsl:templatematch="/">
<root>
<xsl:textdisable-output-escaping="yes">
&lt;![CDATA[
</xsl:text>

<xsl:apply-templatesselect="//office:body"/>

<xsl:textdisable-output-escaping="yes">
]]&gt;
</xsl:text>
</root>
</xsl:template>
Конечно, съедены отступы и пробелы между именами элементов и атрибутов, но в самом коде они есть. И главное вовсе не это, а то, что уже на данном этапе мы получили возможность автоматически окрашивать код в соответствии с тем, как он окрашен в документе, а в данном случае и в Visual Studio. Что касается проблемы с пробелами, то ее можно решить, заменив в выходном потоке пробелы символами с кодом 8194. Фильтр, в котором это сделано находится во вложении ColorizeTextooFilter_SpaceProblemCorrect ed.zip. А вот результат
   <xsl:templatematch="/">
         <root>
             <xsl:textdisable-output-escaping="yes">
  &lt;![CDATA[
  </xsl:text>
  
             <xsl:apply-templatesselect="//office:body"/>          
  
             <xsl:textdisable-output-escaping="yes">
  ]]&gt;
  </xsl:text>
         </root>
     </xsl:template>
Думаю, что тот, кто видел код XSLT в Visual Studio сможет по достоинству оценить результат. Хотя я не уверен, что такой код годится для копипасты, все-таки пробелы не настоящие.

>>
Вложения
Тип файла: zip ColorizeTextOOFilter.zip (1.4 Кб, 344 просмотров)
Тип файла: zip ColorizeTextooFilter_SpaceProblemCorrected.zip (1.5 Кб, 354 просмотров)
Метки libreoffice, openoffice, xslt
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru