XSLT

Холзнер Стивен

Глава 12

Документы XSL-FO

 

 

В этой главе мы продолжим работу с XSL-FO. Здесь мы рассмотрим работу со списками, рисунками и колонками, размещение текста, создание многостраничных последовательностей и другое. По прочтении этой главы вы усвоите основы работы с XSL-FO — по крайней мере, с той частью, которая реализована в современном программном обеспечении. Я начну главу со списков XSL-FO.

 

Создание списков XSL-FO

 

Как мы видели в главе 11, таблицы XSL-FO работают во многом так же, как в HTML, и это в той же мере относится к спискам. Как и в HTML, список XSL выводит вертикальный список элементов. Для создания списков служат четыре элемента XSL-FO:

;

;

;

.

Весь список заключается в элемент , и каждый элемент списка — в элемент . Для создания подписи к элементу списка служит элемент , а для вставки данных в каждый элемент списка — элемент .

Пример lists.xsl (листинг 12.1) преобразует planets.xml в список формата XSL-FO, в котором каждый элемент списка отображает название планеты.

Листинг 12.1. lists.xsl

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

 xmlns:fo="http://www.w3.org/1999/XSL/Format"

 version="1.0">

 

 

  

   

     page-width="300mm" margin-top="10mm" margin-bottom="10mm"

     margin-left="20mm" margin-right="20mm">

    

      margin-left="0mm" margin-right="0mm"/>

    

    

   

  

   

     The Planets Table

    

      provisional-label-separation="5mm">

     

    

    

  

 

 

 

 

   

   

     

     .

    

   

  

  

 

 

  

  

    

  

  

 

 

 

 

 

 

 

 

 

 

 

Вот результирующий документ XSL-FO, lists.fo (листинг 12.2).

Листинг 12.2. lists.fo

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="page">

  

    margin-bottom="10mm" margin-top="0mm"/>

  

 

 

 

  

   The Planets Table

  

    provisional-distance-between-starts="15mm">

   

     

     

       1.

      

     

    

      

       Mercury

     

    

    

   

     

     

       2.

     

     

    

     

       Venus

     

     

    

   

     

     

       3.

      

     

    

     

       Earth

     

     

    

   

  

 

 

Результирующий файл PDF со списком в Adobe Acrobat Reader показан на рис. 12.1.

Рис. 12.1. Список, отформатированный при помощи XSL-FO, в Adobe Acrobat Reader 

Давайте теперь подробнее рассмотрим, как работает lists.fo, и изучим форматирующие объекты для списка.

 

Создание списка: <fo:list-block>

Для начала воспользуйтесь элементом , чтобы создать список XSL-FO; этот объект содержит элементы , содержащие данные списка.

С элементом можно применять следующие свойства:

• общие свойства доступа: source-document, role;

• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;

• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;

• общие свойства полей: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent;

• break-after;

• break-before;

• id;

• keep-together;

• keep-with-next;

• keep-with-previous;

• provisional-distance-between-starts;

• provisional-label-separation;

• relative-position.

Ниже показано, как начинается список в листинге 12.2. В данном случае я задаю значения для свойства provisional-distance-between-starts, определяющего предпочитаемое расстояние от начального отступа метки элемента списка и начального отступа тела элемента списка, и для свойства provisional-label-separation, определяющего предпочитаемое расстояние между концом метки элемента списка (такой, как маркер или номер) и началом тела элемента списка:

 provisional-distance-between-starts="15mm">

 .

 .

 .

 

Создание элементов списка: <fo:list-item>

Затем при помощи элемента нужно поместить в список метку и тело элемента списка. В каждом элементе списка должен присутствовать один из этих объектов.

С элементом можно применять следующие свойства:

• общие свойства доступа: source-document, role;

• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;

• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;

• общие свойства полей: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent;

• break-after;

• break-before;

• id;

• keep-together;

• keep-with-next;

• keep-with-previous;

• relative-align;

• relative-position.

В lists.fo встречается три элемента :

 provisional-distance-between-starts="15mm">

 

  .

  .

  .

 

 

  .

  .

  .

 

 

  .

  .

  .

 

Теперь можно создать метку и добавить данные в каждый элемент списка.

 

Создание меток элемента списка: <fo:list-item-label>

Метка для элемента списка создается элементом , при помощи которого можно перенумеровать или пометить дело элемента списка.

К элементу можно применять следующие свойства:

• общие свойства доступа: source-document, role;

• id;

• keep-together.

В lists.fo я использую элементы для отображения номера планеты в качестве метки элемента списка (lists.xsl находит этот номер при помощи и вставляет его в lists.fo):

 provisional-distance-between-starts="15mm">

 

  

  

    1.

  

  

  .

  .

  .

 

 

  

  

    2.

  

  

  .

  .

  .

 

 

  

  

    3.

  

  

  .

  .

  .

 

Все, что осталось, — добавить в этот список сами данные.

 

Создание тел элементов списка: <fo:list-item-body>

Для включения тела элемента списка служит элемент . Заметьте, что для форматирования тела элемента списка требуемым вам образом вы можете включить в элемент объект .

С элементом можно применять следующие свойства:

• общие свойства доступа: source-document, role;

• id;

• keep-together.

В lists.fo элементы содержат названия планет:

 provisional-distance-between-starts="15mm">

 

  

  

    1.

   

  

 

   

    Mercury

  

 

 

 

  

  

    2.

  

  

 

  

    Venus

  

  

 

 

  

  

    3.

   

  

 

  

    Earth

  

  

 

На этом завершается список, который был показан на рис. 12.1. Работа со списками приемлема в XSL-FO, но я предпочитаю выводить данные при помощи таблиц или простых блоков. Тем не менее, полезно знать, что списки существуют, и ими можно пользоваться.

 

Размещение текста при помощи контейнеров блоков: <fo:block-container>

Процессоры XSL-FO в одном отношении похожи на браузеры HTML: они вставляют блоки в «поток» (flow) страницы, что означает, что эти блоки могут перемещаться по документу, как в HTML-браузере. С другой стороны, иногда бывает важно поместить элементы в странице на определенные места. И в XSL-FO у вас есть возможность разместить элементы либо в абсолютных координатах страницы, либо в координатах относительно других элементов.

Для демонстрации я воспользуюсь элементом , который, как можно предположить, выступает в качестве контейнера блоков. Удобно то, что такие контейнеры блоков поддерживают свойства абсолютного позиционирования, которые сами блоки не поддерживают.

С элементом можно применять следующие свойства:

• общие свойства абсолютной позиции: absolute-position, top, right, bottom, left;

• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;

• общие свойства полей для блоков: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent;

• block-progression-dimension;

• break-after;

• break-before;

• clip;

• display-align;

• height;

• id;

• inline-progression-dimension;

• keep-together;

• keep-with-next;

• keep-with-previous;

• overflow;

• reference-orientation;

• span;

• width;

• writing-mode.

В следующем примере (листинг 12.3) я использую контейнеры блоков как оболочки для блоков, которые я хочу поместить в определенные места страницы

Листинг 12.3. blockcontainer.fo

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="page">

  

    margin-bottom="10mm" margin-top="0mm"/>

  

 

 

 

  

  

    position="absolute">

   

     font-family="sans-serif" font-weight="bold" font-size="14pt">

     Starpowder

    

   

     font-family="sans-serif" font-size="14pt">

     The Starpowder Building:

    

   

     font-family="sans-serif" font-size="14pt">

     1 Starpowder Avenue

    

   

     font-family="sans-serif" font-size="14pt">

     New York. NY. 10011

   

   

  

    position="absolute">

   

     font-family="sans-serif" font-size="23pt">

     Invoice

    

   

  

    border-width="1pt" height="0.7cm" width="3.5cm" top="1.2cm"

    left="12.0cm" padding="2pt" position="absolute">

    

     font-family="sans-serif" font-size="12pt">

     Date

    

   

   

    border-width="1pt" height="0.7cm" width="3.5cm" top="1.9cm"

    left="12.0cm" padding="2pt" position="absolute">

    

     font-family="sans-serif" font-size="12pt">

     January 1, 2002

    

   

  

    border-width="1pt" height="0.7cm" width="3.5cm" top="1.2cm"

    left="15.5cm" padding="2pt" position="absolute">

    

     font-family="sans-serif" font-size="12pt">

     Terms

   

  

  

    border-width="1pt" height="0.7cm" width="3.5cm" top="1.9cm"

    left="15.5cm" padding="2pt" position="absolute">

    

     font-family="sans-serif" font-size="12pt">

     Immediate

    

  

  

    border-width="1pt" height="1.0cm" width="9cm" top="3cm"

    left="0cm" padding="2pt" position="absolute">

    

     font-family="sans-serif" font-size="18pt">

     Description of Service

    

   

  

    border-width="1pt" height="4cm" width="9cm" top="4.0cm"

    left="0cm" padding="2pt" position="absolute">

   

     font-family="sans-serif" font-size="12pt">

    

  

  

    border-width="1pt" height="1.0cm" width="9cm" top="3cm"

    left="10cm" padding="2pt" position="absolute">

    

     font-family="sans-serif" font-size="18pt">

     Address for Payment:

    

  

  

    border-width="1pt" height="4cm" width="9cm" top="4.0cm"

    left="10cm" padding="2pt" position="absolute">

   

     font-family="sans-serif" font-size="12pt">

   

   

 

 

Документ PDF, который процессор fop создаст из blockcontainers.fo, показан на рис. 12.2. Как можно видеть на рисунке, я поместил различные блоки в разные места документа. Некоторые прямоугольники должны быть размещены сразу же поверх других, поэтому в данном случае размещение играет важную роль.

Рис. 12.2. Применение контейнеров блоков 

На самом деле работать с контейнерами блоков просто. Взгляните, например, на прямоугольник «Description of Service» (Описание услуги) на рис. 12.2. Я создал его при помощи двух контейнеров блоков: один из них содержит заголовок «Description of Service», а второй — пустой прямоугольник сразу под первым. Для создания прямоугольника заголовка я применил элемент , указав размеры прямоугольника в свойствах height (высота) и width (ширина) и задав границу в свойстве border-width. Положение прямоугольника на странице я задал, установив свойство position в absolute и установив свойства left (левый) и top (верхний) для размещения верхнего левого угла прямоугольника по отношению к верхнему левому углу страницы:

 border-width="1pt" height="1.0cm" width="9cm" top="3cm"

 left="0cm" padding="2pt" position="absolute">

 .

 .

 .

Теперь я могу включить в контейнер блок, содержащий заголовок «Description of Service»:

 border-width="1pt" height="1.0cm" width="9cm" top="3cm"

 left="0cm" padding="2pt" position="absolute">

 

  font-family="sans-serif" font-size="18pt">

  Description of Service

 

После этого я размещаю пустой прямоугольник сразу под прямоугольником заголовка:

 border-width="1pt" height="1.0cm" width="9cm" top="3cm"

 left="0cm" padding="2pt" position="absolute">

 

  font-family="sans-serif" font-size="18pt">

  Description of Service

 

 border-width="1pt" height="4cm" width="9cm" top="4.0cm"

 left="0cm" padding="2pt" position="absolute">

 

  font-family="sans-serif" font-size="12pt">

 

Результат показан на рис. 12.2. Я считаю эту возможность одной из самых важных в XSL-FO: вы можете помещать элементы в точности туда, куда вам нужно. Допустимо полагаться на поток объектов, создаваемый процессором XSL-FO, но иногда требуется расположить объекты в определенном месте, и теперь вы знаете, как это сделать.

 

Встроенные форматирующие объекты

 

Помимо объектов блока, в XSL-FO можно также создавать встроенные (inline) объекты. Встроенный объект представляет собой часть большей форматирующей области, такой как блок; например, встроенный объект может представлять одно или два слова в блоке. Встроенные объекты обычно применяются для форматирования части текста после того, как этот текст был размещен на странице в соответствии с обычным потоком. Можно увеличить первый символ в абзаце, выделить всю первую строку голубым цветом, вставить номера страниц, добавить рисунки и т.д.

Встроенные объекты можно применять для форматирования частей текста блока; например, в главе 11 мы видели, как свойство text-decoration объекта применялось для подчеркивания текста:

 

  font-family="Times">

  

   Mass;

  :

  

  [Earth = 1]

 

В следующем списке перечислены встроенные форматирующие элементы:

;

;

;

;

;

;

;

;

;

.

Я опишу несколько самых распространенных встроенных элементов, начав с самого .

 

Создание встроенных областей: <fo:inline>

Как вы уже видели в главе 11, при помощи элемента вы можете форматировать части текста, задавая для них задний фон, подчеркивая текст или заключая текст в границы. Элемент позволяет форматировать встроенную область из нескольких слов в блоке текста как если бы они сами представляли собой блок.

С элементом можно применять следующие свойства:

• общие свойства доступа: source-document, role;

• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;

• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;

• общие свойства шрифтов: font-family, font-size, font-stretch, font-size-adjust, font-style, font-variant, font-weight;

• общие свойства встроенных полей: space-end, space-start;

• alignment-adjust;

• baseline-identifier;

• baseline-shift;

• color;

• dominant-baseline;

• id;

• keep-together;

• keep-with-next;

• keep-with-previous;

• line-height;

• line-height-shift-adjustment;

• relative-position;

• text-decoration;

• visibility;

• z-index.

Например, мы уже видели, как подчеркнуть отдельное слово внутри остального текста при помощи свойства text-decoration:

 

  font-familу="Times">

  

   Mass

  :

  

  [Earth = 1]

 

Мы еще встретим элемент , когда будем рассматривать сноски позже в этой главе.

 

Обработка отдельных символов: <fo:character>

Как можно догадаться по имени, объект позволяет работать с отдельными символами в документе. Одна из областей применения — случай, когда нужно заменить определенные символы на другие. В следующем примере я выбираю элемент с именем и заменяю его символы на символ «*»:

 

 

 

При помощи элемента можно форматировать отдельные символы, как в следующем случае, где символы в слове «HELLO» выделяются различными цветами:

С элементом можно применять следующие свойства:

• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;

• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;

• общие свойства шрифтов: font-family, font-size, font-stretch, font-size-adjust, font-style, font-variant, font-weight;

• общие свойства переносов: country, language, script, hyphenate, hyphenation-character, hyphenation-push-character-count, hyphenation-remain-character-count;

• общие свойства встроенных полей: space-end, space-start;

• alignment-adjust;

• treat-as-word-space;

• baseline-identifier;

• baseline-shift;

• character;

• color;

• dominant-baseline;

• font-height-override-after;

• font-height-override-before;

• glyph-orientation-horizontal;

• glyph-orientation-vertical;

• id;

• keep-with-next;

• keep-with-previous;

• letter-spacing;

• line-height;

• line-height-shift-adjustment;

• relative-position;

• score-spaces;

• suppress-at-line-break;

• text-decoration;

• text-shadow;

• text-transform;

• word-spacing.

 

Создание номеров страниц: <fo:page-number>

Встроенный форматирующий объект создает встроенную область, отображающую номер текущей страницы. Например:

 You are now reading page .

С элементом можно применять следующие свойства:

• общие свойства доступа: source-document, role;

• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;

• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;

• общие свойства шрифтов: font-family, font-size, font-stretch, font-size-adjust, font-style, font-variant, font-weight;

• общие свойства встроенных полей: space-end, space-start;

• alignment-adjust;

• baseline-identifier;

• baseline-shift;

• dominant-baseline;

• id;

• keep-with-next;

• keep-with-previous;

• letter-spacing;

• line-height;

• line-height-shift-adjustment;

• relative-position;

• score-spaces;

• text-decoration;

• text-shadow;

• text-transform;

• word-spacing.

Пример применения номеров страниц будет показан при обсуждении последовательностей страниц в конце этой главы.

 

Вставка графики: <fo:external-graphic>

Популярный элемент при форматировании XSL-FO — , при помощи которого можно вставить в документ рисунок.

С элементом можно применять следующие свойства:

• общие свойства доступа: source-document, role;

• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;

• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;

• общие свойства встроенных полей: space-end, space-start;

• alignment-adjust;

• baseline-identifier;

• baseline-shift;

• block-progression-dimension;

• content-height;

• content-type;

• content-width;

• dominant-baseline;

• height;

• id;

• inline-progression-dimension;

• keep-with-next;

• keep-with-previous;

• line-height;

• line-height-shift-adjustment;

• relative-position;

• overflow;

• scaling;

• scaling-method;

• src;

• width.

Как в HTML, можно устанавливать размер рисунка в документе — в XSL-FO для этого служат свойства content-height, content-width и scaling; если их не задать, рисунок будет отображен в своем первоначальном размере. Следующий пример, graphics.fo (листинг 12.4), отображает рисунок, xslfo.jpg, и подпись к нему:

Листинг 12.4. graphics.fo

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="page">

  

    margin-bottom="10mm" margin-top="0mm"/>

  

 

 

 

  

  

    font-size="36pt" text-align="center">

    Using Graphics

   

  

   

   

  

    An image embedded in a document.

   

  

 

Документ PDF, созданный из graphics.fo, показан на рис. 12.3.

Рис. 12.3. Отображение рисунка при помощи форматирующих объектов 

Вставить рисунок в результирующий документ легко, если вставку поддерживает ваше программное обеспечение. Процессор fop теперь поддерживает рисунки (еще несколько версий назад он этого не делал), поэтому вы можете вставлять рисунки при помощи элемента следующим образом:

 

 

Форматирование первых строк: <fo:initial-property-set>

При помощи элемента вы можете задать свойства для первой строки в блоке и отформатировать ее. В следующем примере я форматирую первую строку блока капителью (small caps) при помощи свойства font-variant (которое, кстати, fop не поддерживает):

 

 This text will be displayed in the result document.

 The first line will be dis played using small caps.

С элементом можно применять следующие свойства:

• общие свойства доступа: source-document, role;

• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;

• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;

• общие свойства шрифтов: font-family, font-size, font-stretch, font-size-adjust, font-style, font-variant, font-weight;

• color;

• id;

• letter-spacing;

• line-height;

• line-height-shift-adjustment;

• relative-position;

• score-spaces;

• text-decoration;

• text-shadow;

• text-transform;

• word-spacing.

На этом мы заканчиваем обзор встроенных форматирующих объектов; в следующих разделах мы рассмотрим подстрочный форматирующий объект — сноски.

 

Создание сносок: <fo:footnote> и <fo:footnote-body>

Сноски называют «подстрочными» (out-of-line) форматирующими объектами, потому что они добавляют текст в нижнюю часть страницы. Сноска создается при помощи элемента , а текст тела сноски — при помощи элемента . В текущей спецификации XSL-FO эти элементы не поддерживают никаких свойств.

В следующем примере, footnotes.fo (листинг 12.5), я использую две сноски в теле документа и добавляю в них текст.

Листинг 12.5. footnotes.fo

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="page">

  

    margin-bottom="10mm" margin-top="0mm"/>

  

 

 

 

  

  

    font-size="36pt" text-align="center">

    Using Footnotes

   

  

    This:

   

     footnote

     

       1

     

     

     

      

       1. Here's the first footnote's text.

      

     

    

    refers to text at the bottom of this page.

   

  

    This second;

    

     footnote

     

       2

     

     

     

      

       2. And here's the second footnote's text.

      

     

    

    also refers to text at the bottom of this page.

   

 

 

Текст, дополненный верхними индексами для сносок 1 и 2, показан на рис. 12.4. Текст двух сносок внизу той же самой страницы показан на рис. 12.5.

Рис. 12.4. Текст со сносками 

Рис. 12.5. Текст сносок внизу страницы

Для создания текста сносок применяется элемент . При работе с процессором fop вы должны самостоятельно добавлять фактический номер сноски в верхнем индексе — такой, как 1 или 2. Вот как это выглядит в footnotes.fo, где для создания верхнего индекса я установил свойство vertical-align встроенного элемента в «super»:

 This:

 

  footnote

  

    1

  

 

  .

  .

  .

Чтобы создать текст сноски, появляющийся внизу страницы, нужно применить элемент внутри элемента . Сам процессор fop не нумерует сноски, поэтому за добавление номеров сносок отвечаете вы:

 This

 

  footnote

  

    1

  

  

  

   

    1. Here's the first footnote's text.

  

  

 

 refers to text at the bottom of this page.

 

Этот код на XSL-FO создает и первый текст со сносками на рис. 12.4, и сам текст первых сносок, показанный на рис. 12.5.

 

Создание ссылок: <fo:basic-link>

Еще одним мощным средством XSL-FO является возможность использовать ссылки от документа к документу. В данный момент эта возможность поддерживается в процессоре fop при помощи элемента XSL-FO , который действует во многом похоже на обычную гиперссылку. С элементом можно применять следующие свойства:

• общие свойства доступа: source-document, role;

• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;

• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;

• общие встроенные свойства встроенных полей: space-end, space-start;

• общие свойства относительного расположения: top, right, bottom, left, relative-position;

• alignment-adjust;

• alignment-baseline;

• baseline-shift;

• destination-placement-offset;

• dominant-baseline;

• external-destination;

• id;

• indicate-destination;

• internal-destination;

• keep-together;

• keep-with-next;

• keep-with-previous;

• line-height;

• line-height-shift-adjustment;

• show-destination;

• target-processing-context;

• target-presentation-context;

• target-stylesheet.

Следующий пример, links.fo (листинг 12.6), содержит ссылку на документ PDF, созданный ранее в этой главе, graphics.pdf.

Листинг 12.6. links.fo

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="page">

  

    margin-bottom="10mm" margin-top="0mm"/>

  

 

 

 

  

  

    font-size="36pt" text-align="center">

    Using Links

   

  

    If you'd like to see some images, click

   

     here

    .

   

 

 

Документ PDF, созданный на основе links.fo, показан на рис. 12.6. Заметьте, что я явно подчеркнул ссылку, чтобы она была больше похожа на гиперссылку. Когда в Adobe Acrobat вы помещаете указатель мыши над ссылкой, он меняет свою форму и становится в точности такой формы, которую Internet Explorer использует для гиперссылок, как показано на рис. 12.6. При щелчке на ссылке Acrobat переходит на graphics.pdf (который для работы примера нужно поместить в тот же каталог, что и links.pdf), отображая этот новый документ.

Рис. 12.6. Поддержка ссылок в XSL-FO 

В данном случае создать ссылку очень просто — достаточно установить свойство external-destination элемента в «graphics.pdf»:

 If you'd like to see some images, click

 

  .

  .

  .

 .

Теперь осталось только добавить подчеркнутый текст, чтобы пользователь мог щелкнуть по нему и перейти к новому документу. Конечно, не обязательно выделять текст подчеркиванием; но иначе ничто не будет указывать на то, что текст является ссылкой, — за исключением указателя мыши, который изменит форму при перемещении над текстом. Подчеркнутый текст можно добавить следующим образом:

 If you'd like to see some images, click

 

  here

 .

Пока в XSL-FO реализованы только обычные ссылки (basic link), как показано в примере. Но если вы знакомы со спецификациями XML для XPointer и XLink, вам следует ожидать в будущем значительного развития в этой области.

 

Создание колонок

При помощи XSL-FO можно разбить текст на колонки. Создать колонки несложно, нужно только воспользоваться свойствами column-count и column-gap элемента и предоставить все остальное процессору XSL-FO.

Давайте рассмотрим пример, columns.fo. Чтобы разбить текст на две колонки с расстоянием в четверть дюйма между ними, я установил свойство column-count в «2», а свойство column-gap в «0.25in»:

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="page">

  

    column-count="2" column-gap="0.25in"/>

  

   

 

 

 .

 .

 .

Теперь осталось только вывести в этих колонках какой-либо текст; заметьте, что я также создаю заголовок при помощи элемента , о котором будет еще сказано в следующем разделе (листинг 12.7).

Листинг 12.7. columns.fo

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="page">

  

    column-count="2" column-gap="0.25in"/>

  

   

 

 

 

 

   

    font-family="sans-serif" line-height="48pt">

    Creating Columns

   

  

 

  

    space-after="15pt">

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

  

 

 

Результат обработки этого документа, columns.pdf, показан на рис. 12.7.

Рис. 12.7. Создание колонок при помощи XSL-FO 

 

Последовательности страниц и нумерация страниц

Пока я использовал один и тот же шаблон страницы для всех страниц в рассмотренных нами документах XSL-FO. Если содержимое документа занимает более одной страницы, процессор XSL-FO использует тот же шаблон страницы для всех последующих страниц.

Но вам может быть нужно использовать различные шаблоны страницы в разных местах документа. Например, первую страницу нужно отформатировать отлично от следующих. При помощи XSL-FO это можно сделать.

Каждый элемент , который я применял во всех примерах XSL-FO, ссылается либо на шаблон страницы, либо на элемент . При помощи элемента вы можете задать различные шаблоны страницы для последовательности страниц.

Пример pages.fo продемонстрирует вышесказанное. Я создам для первой страницы один простой шаблон страницы, «first» (первая), в котором текстовая часть смещена вниз страницы, для чего я устанавливаю свойство margin-top элемента в «50mm»:

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="first">

  

    margin-bottom="10mm" margin-top="50mm"/>

  

   

  

  .

  .

  .

Для всех остальных страниц я создам новый шаблон страницы, «rest» (остальные), в котором текст будет начинаться сверху страницы, для чего я устанавливаю свойство margin-top элемента в «20mm»:

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="first">

   .

   .

   .

 

 

   margin-bottom="15mm" margin-top="15mm" page-width="300mm"

   page-height="400mm" master-name="rest">

  

    margin-bottom="10mm" margin-top="20mm"/>

  

   

 

  .

  .

  .

Чтобы создать шаблон последовательности страниц, использующий простые шаблоны страниц «first» и «rest», я применяю элемент :

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="first">

   .

   .

   .

 

 

   margin-bottom="15mm" margin-top="15mm" page-width="300mm"

   page-height="400mm" master-name="rest">

   .

   .

   .

 

 

   .

   .

   .

 

 

С элементом вы можете применять следующее свойство:

• master-name.

Здесь я просто назвал новую последовательность страниц «sequence» (последовательность). Я создаю шаблон последовательности страниц повторяющегося типа, и для задания имен шаблонов страниц в новой последовательности служит элемент :

 

  .

  .

  .

 

Очередное свойство элемента определяет, сколько раз полагается повторять последовательность:

• maximum-repeats.

Наконец, надо задать шаблоны страниц, которые будут использованы в шаблоне последовательности, при помощи элемента . Этот элемент ссылается на шаблон страницы при помощи свойства master-name, и этот шаблон страницы будет использован при выполнении определенного условия. Чтобы выбрать первую страницу, нужно установить свойство page-position в «first», а для выбора остальных страниц — в «rest»:

 

 

   master-name="first" page-position="first"/>

  

   master-name="rest" page-position="rest"/>

 

С элементом можно применять следующие свойства:

• master-name;

• page-position;

• odd-or-even;

• blank-or-not-blank.

Теперь при создании последовательности страниц с помощью элемента я указываю, что процессор XSL-FO должен использовать шаблон последовательности, «sequence», который я только что создал, установив атрибут master-name элемента :

 .

 .

 .

номером текущей страницы, так что установить нумерацию страниц не составит труда. Чтобы вывести номер в верхней части каждой страницы, я создаю верхний колонтитул страницы при помощи элемента .

Существует два вида потоковых объектов: и . Мы уже видели, как при помощи добавляются страницы в поток документа. Элемент используется для добавления в документ верхних и нижних колонтитулов. С можно применять следующее свойство:

• flow-name.

Для создания колонтитула нужно только поместить элемент перед элементом в последовательности страниц:

 

 

   font-family="sans-serif" line-height="36pt">

   Sample Document p.

   

  

 

 

 .

 .

 .

УСТАНОВКА НАЧАЛЬНОГО НОМЕРА СТРАНИЦЫ

Для установки начального номера страницы в последовательности служит свойство initial-page-number элемента <fo:page-sequence>, что позволяет вам, например, отдельно форматировать главы, начиная каждую главу с правильного номера страницы.

Наконец, нам осталось только включить в pages.fo (листинг 12.8) образец форматируемого текста, так чтобы документ содержал более одной страницы.

Листинг 12.8. pages.fo

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="first">

  

    margin-bottom="10mm" margin-top="50mm"/>

  

   

 

 

   margin-bottom="15mm" margin-top="15mm" page-width="300mm"

   page-height="400mm" master-name="rest">

  

    margin-bottom="10mm" margin-top="20mm"/>

  

   

 

 

   

   

     master-name="first" page-position-"first"/>

   

     master-name="rest" page-position="rest"/>

   

  

 

 

 

   

    font-family="sans-serif" line-height="36pt">

    Sample Document p.

    

   

  

 

  

    text-align="center" space-after="24pt">

    Sample Document

   

  

    color="gray">

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

    Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

   

  

 

Теперь все готово. Первая страница, созданная pages.fo, показана на рис. 12.8; как можно заметить, текст смещен вниз.

Рис. 12.8. Первая страница, отформатированная при помощи XSL-FO 

Текст на второй странице начинается сверху, как видно на рис. 12.9.

Рис 12.9. Вторая страница, отформатированная при помощи XSL-FO

Как можно заметить из листинга 12.8, я включил в pages.fo большое число строк, не содержащих ничего, кроме слов «Sample Text.», для того чтобы гарантированно получить многостраничный документ. Но для перехода на новую страницу не обязательно располагать большим количеством текста: можно также установить свойство break-after элемента в «page», и процессор XSL-FO перейдет на новую страницу после текущего блока:

 

  text-align="center" space-after="24pt">

  Sample Document

 

 

  color="gray" break-after="page">

  Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

  Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

  Sample Text. Sample Text.

 

 

  color="gray">

  Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

  Sample Text. Sample Text. Sample Text. Sample Text. Sample Text.

  Sample Text. Sample Text.

 

Вот и все. Теперь процессор XSL-FO перейдет на следующую страницу после блока. Для создания разрывов можно использовать следующие свойства и настройки:

• break-after. Указывает, что последняя область, созданная при обработке данного форматирующего объекта, будет последней помещенной в определенный контекст. Устанавливается в auto | column | page | even-page | odd-page | inherit;

• break-before. Указывает, что первая созданная область должна быть первой, помещенной в определенный контекст. Устанавливается в auto | column | page | even-page | odd-page | inherit.

Рассмотрим еще один пример применения последовательностей страниц. Если вы посмотрите на книги, напечатанные на таких западных языках, как английский, немецкий или французский, вы заметите, что страницы с четными номерами, как правило, расположены слева, а страницы с нечетными номерами — справа. Четные и нечетные страницы можно отформатировать по-разному: например, можно задать дополнительное пространство поля у переплета, что даст дополнительное пространство левого поля для нечетных страниц и дополнительное пространство правого поля для четных.

Чтобы реализовать такое форматирование, можно применить атрибут odd-or-even элемента , устанавливая его в значение «even» или «odd», выбирая соответственно четные или нечетные страницы:

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="leftpage">

  

    margin-bottom="10mm" margin-top="50mm"/>

   

   

 

 

   margin-bottom="10mm" margin-top="10mm" page-width="300mm"

   page-height="400mm" master-name="rightpage">

  

    margin-bottom="10mm" margin-top="20mm"/>

   

  

  

 

  

   

     master-name="rightpage" odd-or-even="odd"/>

   

     master-name="leftpage" odd-or-even="even"/>

   

  

 

 

  .

  .

  .

Теперь у страниц, расположенных справа, левое поле у переплета книги будет расширено, а у страниц, расположенных слева, также будет расширено правое поле.

Как видите, форматирующие объекты — довольно объемная тема, и, как я уже говорил, для большой части материала в этой книге не хватает места. Дополнительные подробности можно узнать на web-узле W3C, www.w3.org/TR/xsl/. Существует не так уж много пакетов программ для работы с форматирующими объектами, хотя в будущем ситуация должна измениться.

На этом мы заканчиваем рассмотрение XSL-FO — а вместе с ним и книгу. Вы познакомились со всеми видами XSLT-преобразований: из XML в XML, в HTML, в XHTML, в RTF, в простой текст, в JavaScript, в реляционные базы данных, и теперь — в XSL-FO. Вы увидели все возможные элементы, атрибуты и функции XSLT и рассмотрели много работающих примеров. Теперь осталось только использовать всю эту мощь в работе. Удачи вам в применении XSLT!