Книга: XSLT

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

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

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

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

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

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

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <fo:layout-master-set>
  <fo:simple-page-master margin-right="20mm" margin-left="20mm"
   margin-bottom="10mm" margin-top="10mm" page-width="300mm"
   page-height="400mm" master-name="first">
   <fo:region-body margin-right="0mm" margin-left="0mm"
    margin-bottom="10mm" margin-top="50mm"/>
   <fo:region-after extent="10mm"/>
   <fo:region-before extent="10mm"/>
  </fo:simple-page-master>
  .
  .
  .

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

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <fo:layout-master-set>
  <fo:simple-page-master margin-right="20mm" margin-left="20mm"
   margin-bottom="10mm" margin-top="10mm" page-width="300mm"
   page-height="400mm" master-name="first">
   .
   .
   .
  </fo:simple-page-master>
  <fo:simple-page-master margin-right="25mm" margin-left="25mm"
   margin-bottom="15mm" margin-top="15mm" page-width="300mm"
   page-height="400mm" master-name="rest">
   <fo:region-body margin-right="0mm" margin-left="0mm"
    margin-bottom="10mm" margin-top="20mm"/>
   <fo:region-after extent="10mm"/>
   <fo:region-before extent="10mm"/>
  </fo:simple-page-master>
  .
  .
  .

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

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <fo:layout-master-set>
  <fo:simple-page-master margin-right="20mm" margin-left="20mm"
   margin-bottom="10mm" margin-top="10mm" page-width="300mm"
   page-height="400mm" master-name="first">
   .
   .
   .
  </fo:simple-page-master>
  <fo:simple-page-master margin-right="25mm" margin-left="25mm"
   margin-bottom="15mm" margin-top="15mm" page-width="300mm"
   page-height="400mm" master-name="rest">
   .
   .
   .
  </fo:simple-page-master>
  <fo:page-sequence-master master-name="sequence">
   .
   .
   .
  </fo:page-sequence-master>
 </fo:layout-master-set>

С элементом <fo:page-sequence-master> вы можете применять следующее свойство:

master-name.

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

<fo:page-sequence-master master-name="sequence">
 <fо:repeatable-page-master-alternatives>
  .
  .
  .
 </fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>

Очередное свойство элемента <fo:repeatable-page-master-alternatives> определяет, сколько раз полагается повторять последовательность:

maximum-repeats.

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

<fo:page-sequence-master master-name="sequence">
 <fo:repeatable-page-master-alternatives>
  <fо:conditional-page-master-reference
   master-name="first" page-position="first"/>
  <fo:conditional-page-master-reference
   master-name="rest" page-position="rest"/>
 </fо:repeatable-page-master-alternatives>
</fo:page-sequence-master>

С элементом <fo:conditional-page-master-reference> можно применять следующие свойства:

master-name;

page-position;

odd-or-even;

blank-or-not-blank.

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

<fo:page-sequence master-name="sequence">
 .
 .
 .

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

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

flow-name.

Для создания колонтитула нужно только поместить элемент <fo:static-content> перед элементом <fo:flow> в последовательности страниц:

<fo:page-sequence master-name="sequence">
 <fo:static-content flow-name="xsl-region-before">
  <fo:block text-align="end" font-size="24pt"
   font-family="sans-serif" line-height="36pt">
   Sample Document p.
   <fo:page-number/>
  </fo:block>
 </fo:static-content>
 <fo:flow flow-name="xsl-region-body">
 .
 .
 .

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

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

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

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

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <fo:layout-master-set>
  <fo:simple-page-master margin-right="20mm" margin-left="20mm"
   margin-bottom="10mm" margin-top="10mm" page-width="300mm"
   page-height="400mm" master-name="first">
   <fo:region-body margin-right="0mm" margin-left="0mm"
    margin-bottom="10mm" margin-top="50mm"/>
   <fo:region-after extent="10mm"/>
   <fo:region-before extent="10mm"/>
  </fo:simple-page-master>
  <fo:simple-page-master margin-right="25mm" margin-left="25mm"
   margin-bottom="15mm" margin-top="15mm" page-width="300mm"
   page-height="400mm" master-name="rest">
   <fo:region-body margin-right="0mm" margin-left="0mm"
    margin-bottom="10mm" margin-top="20mm"/>
   <fo:region-after extent="10mm"/>
   <fо:region-before extent="10mm"/>
  </fo:simple-page-master>
  <fo:page-sequence-master master-name="sequence">
   <fо:repeatable-page-master-alternatives>
    <fo:conditional-page-master-reference
     master-name="first" page-position-"first"/>
    <fo:conditional-page-master-reference
     master-name="rest" page-position="rest"/>
   </fо:repeatable-page-master-alternatives>
  </fo:page-sequence-master>
 </fo:layout-master-set>
 <fo:page-sequence master-name="sequence">
  <fo:static-content flow-name="xsl-region-before">
   <fo:block text-align="end" font-size="24pt"
    font-family="sans-serif" line-height="36pt">
    Sample Document p.
    <fo:page-number/>
   </fo:block>
  </fo:static-content>
  <fo:flow flow-name="xsl-region-body">
   <fo:block font-size="36pt" font-family="Times"
    text-align="center" space-after="24pt">
    Sample Document
   </fo:block>
   <fo:block font-size="24pt" font-family="sans-serif"
    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.
   </fo:block>
  </fo:flow>
 </fo:page-sequence>
</fo:root>

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


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

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


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

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

<fo:flow flow-name="xsl-region-body">
 <fo:block font-size="36pt" font-family="Times"
  text-align="center" space-after="24pt">
  Sample Document
 </fo:block>
 <fo:block font-size="24pt" font-family="sans-serif"
  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.
 </fo:block>
 <fo:block font-size="24pt" font-family="sans-serif"
  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.
 </fo:block>
</fo:flow>

Вот и все. Теперь процессор 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 элемента <fo:conditional-page-master-reference>, устанавливая его в значение «even» или «odd», выбирая соответственно четные или нечетные страницы:

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <fo:layout-master-set>
  <fo:simple-page-master margin-right="50mm" margin-left="20mm"
   margin-bottom="10mm" margin-top="10mm" page-width="300mm"
   page-height="400mm" master-name="leftpage">
   <fo:region-body margin-right="0mm" margin-left="0mm"
    margin-bottom="10mm" margin-top="50mm"/>
   <fo:region-after extent="10mm"/>
   <fo:region-before extent="10mm"/>
  </fo:simple-page-master>
  <fo:simple-page-master margin-right="20mm" margin-left="50mm"
   margin-bottom="10mm" margin-top="10mm" page-width="300mm"
   page-height="400mm" master-name="rightpage">
   <fo:region-body margin-right="0mm" margin-left="0mm"
    margin-bottom="10mm" margin-top="20mm"/>
   <fo:region-after extent="10mm"/>
   <fo:region-before extent="10mm"/>
  </fo:simple-page-master>
  <fo:page-sequence-master master-name="alternatingpages">
   <fо:repeatable-page-master-alternatives>
    <fo:conditional-page-master-reference

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

    <fo:conditional-page-master-reference
     master-name="leftpage" odd-or-even="even"/>
   </fo:repeatable-page-master-alternatives>
  </fo:page-sequence-master>
 </fo:layout-master-set>
 <fo:page-sequence master-name="alternatingpages">
  .
  .
  .

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

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

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

Оглавление книги


Генерация: 1.165. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз