<?xml version="1.0" encoding="iso-8859-2" standalone="yes"?>
<!-- $Id: fointro.xml,v 1.2 2003/01/02 21:03:06 tomek Exp $ -->
<!-- (c) T.Przechlewski 2002, (tomasz@gnu.univ.gda.pl)                     -->
<!-- Zezwala się na wykorzystanie tego dokumentu na warunkach licencji GPL -->
<!-- patrz: http://www.gnu.org/licenses/gpl.html                           -->
<!DOCTYPE article SYSTEM "pmla.dtd" [
 <!ENTITY XSL   "XSL"    >
 <!ENTITY XSLT  "XSLT"   >
 <!ENTITY XML   "XML"    >
 <!ENTITY XPATH "XPath"  >
 <!ENTITY FO    "FO"     >
 <!ENTITY XSLFO "XSLFO"  >
]>
<!-- exploder sie gubi -->
<?xml-stylesheet href="pmla2h.css" type="text/css"?>
<!-- ;; -->
<article>
  <title>Praktyczne wprowadzenie do standardu XSL</title>
  <author>Tomasz Przechlewski</author>
  <email>tomasz@gnu.univ.gda.pl</email>
<abstract>
 <para>
  Język formatowania &XSL; składa się z trzech rekomendacji: &XSLT;,
  &XPATH; oraz &FO; opisujących w jaki sposób zamienić dokument &XML;
  z postaci strukturalnej do postaci prezentacyjnej.  Dwie pierwsze są
  związane z przekształcaniem dokumentów &XML;, rekomendacja &FO; jest
  specyfikacją standardowych obiektów formatujących, tj. obiektów
  definiujących semantykę samego formatowania.
 </para>
 <para>
  Artykuł zawiera wprowadzenie do standardu &XSLFO; oraz przedstawia
  rozwijaną w ramach projektu Apache aplikację FOP umożliwiającą
  zamianę pliku &XML; na dokument w formacie PDF. 
  Pozostałe części języka XSL nie są opisane.
 </para>
</abstract>
<section>
<title>Wprowadzenie do &XSLFO;</title>
<para>
&XSLFO; jest skomplikowanym językiem o dużych możliwościach,
zawierającym ponad 50 różnych ,,obiektów formatujących'', począwszy od
najprostszych, takich jak prostokątne bloki tekstu, poprzez
wyliczenia, tabele i odsyłacze. Obiekty te można formatować
wykorzystując przeszło 200 różnych właściwości 
(<emph class="en">properties</emph>), takich jak: kroje, odmiany i wielkości
pisma, odstępy, kolory itp.  W tym dokumencie przedstawione jest
absolutne minimum informacji na temat standardu &XSLFO;.
</para>
<para>
Dokument &XSLFO; to <emph>specyficzny</emph> dokument &XML;, którego elementy
i atrybuty nie opisują struktury dokumenty ale wyłącznie jego postać
graficzną. Takie podejście różni &XSLFO; od arkuszy stylów typu CSS,
w których polecenia formatujące są (zwykle) oddzielone od dokumentu,
którego dotyczą.  
&XSLFO; pod tym względem przypomina raczej tradycyjne
systemy przetwarzania tekstu takie jak TeX, czy troff. 
Dokument &XSLFO; winien być generowany automatycznie 
na podstawie danych zapisanych w innym formacie
(np. ,,strukturalnego'' dokumentu &XML; lub 
informacji z relacyjnej bazy danych),
a po wykorzystaniu usunięty.
Format &XSLFO; nie jest przeznaczony ani do przechowywania informacji,
ani do jej wymiany.
</para>
<para>
W typowym scenariuszu dokument &XSLFO; jest tworzony za pomocą
odpowiedniego arkusza stylu XSLT 
(por. rys. <ref src="pic-processing"/>).
W poniższym przykładowym fragmencie arkusza
XSLT element <verb class="xslel">para</verb> wyjściowego dokumentu
jest transformowany do elementu <verb class="xslel">fo:block</verb>:
</para>
<verbatim>
&lt;template match="para">
 &lt;fo:block space-after.optimum="0pt" hyphenate="true" >
&lt;xsl:apply-templates/> &lt;/fo:block>
&lt;/xsl:template>
</verbatim>
<para>
W tym artykule pominięto zagadnienie konwersji dokumentów &XML; za
pomocą arkusza XSLT koncentrując się wyłącznie na standardzie
&XSLFO;.  Doskonały wstęp do standardów &XSLT; i &XPATH; można znaleźć
w <cite src="Olko"/>.
</para>
<figure id="pic-processing">
 <title>Typowy scenariusz przetwarzania dokumentu &XSLFO;</title>
 <graphic format="EPS" src="process.eps"/>
 <graphic format="JPG" src="process.jpg"/>
</figure>
<para>
Cały dokument &XSLFO; zawarty jest wewnątrz elementu <verb
class="xslel">fo:root</verb>.  Element ten zawiera (w podanej niżej
kolejności):
</para>
<itemize>
<item><para> dokładnie jeden element <verb class="xslel">fo:layout-master-set</verb> zawierający
  szablony określające wygląd poszczególnych stron oraz sekwencji
  stron (te ostatnie są opcjonalne, ale typowo są definiowane);
</para></item>

<item><para> zero lub więcej elementów <verb class="xslel">fo:declarations</verb>;
</para></item>

<item><para> jeden lub więcej elementów <verb class="xslel">fo:page-sequance</verb>
 zawierających treść formatowanego dokumentu wraz z opisem
 jego sformatowania i podziału na strony.
</para>
</item>
</itemize>
<para>
Treść formatowanego dokumentu znajduje się wyłącznie wewnątrz elementów
<verb class="xslel">fo:page-sequance</verb>, podczas gdy element
<verb class="xslel">fo:layout-master-set</verb> zawiera definicje szablonów. 
Strukturę dokumentu przedstawiono schematycznie na
rysunku <ref src="pic-fo-struct"/>.
</para>
<figure id="pic-fo-struct">
 <title>Ogólna struktura dokumentu &XSLFO;</title>
 <graphic format="EPS" src="fo-structure.eps"/>
 <graphic format="JPG" src="fo-structure.jpg"/>
 <graphic format="PNG" src="fo-structure.png"/>
 <graphic format="GIF" src="fo-structure.gif"/>
</figure>
<para>
Ponieważ element <verb class="xslel">root</verb> <emph>musi</emph> być
w przypadku dokumentu &XSLFO; związany z przestrzenią nazw
<verb>http://www.w3.org/1999/XSL/Format</verb>, oznacza to, że
przykładowy początek szablonu 
może wyglądać następująco:
</para>
<verbatim>
&lt;?xml version="1.0" encoding="iso-8859-2" ?>
 &lt;fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
</verbatim>
</section>
<section>
<title>Określenie ogólnego układu graficznego dokumentu</title>
<para>
Element <verb class="xslel">fo:layout-master-set</verb> zawiera <emph>co najmniej</emph>
jeden element <verb class="xslel">fo:simple-page-master</verb> lub
<verb class="xslel">fo:page-sequence-master</verb>.
</para>
<para>
Element <verb class="xslel">fo:simple-page-master</verb> 
(dalej określany skrótowo jako
SPM) definiuje układ graficzny pojedynczej strony. Strona może
posiadać do pięciu różnych obszarów definiowanych za pomocą
elementów: 
<verb class="xslel">fo:region-body</verb>,
<verb class="xslel">fo:region-before</verb>,
<verb class="xslel">fo:region-after</verb>,
<verb class="xslel">fo:region-start</verb> oraz
<verb class="xslel">fo:region-end</verb>.  
W przypadku konwencji używanych w drukarstwie europejskim obszary 
te odpowiadają: kolumnie głównej tekstu, paginie
górnej<index>pagina!górna</index>, paginie dolnej<index>pagina!dolna</index>,
marginaliom wewnętrznym  i marginaliom zewnętrznym.
Szczegóły układu graficznego każdego obszaru (tj. wymiary, marginesy, 
ramki, kolory) są określone za pomocą wartości
odpowiednich atrybutów elementu SPM (więcej na ten 
temat dalej w tekście).
</para>
<para>
Specyfikacja obszaru <verb class="xslel">fo:region-body</verb> jest obowiązkowa.
W wersji 1.0 standardu element <verb class="xslel">fo:simple-page-master</verb> stanowi
<emph>jedyny</emph> sposób definiowania układu graficznego stron.
Przyszłe wersje standardu mogą wprowadzić bardziej skomplikowane
układy graficzne stron.
</para>
<para>
Element <verb class="xslel">fo:page-sequence-master</verb> (PSM) określa porządek w jakim
poszczególne strony, zdefiniowane za pomocą SPM, będą zapełniane.
Porządek ten określają elementy-dzieci elementu
<verb class="xslel">fo:page-sequence-master</verb>:
</para>
<description>
<descritem>
<term><verb class="xslel">fo:single-page-master-reference</verb></term>
<descr><para> powoduje sformatowanie
  dokładnie jednej strony o układzie graficznym określonym wartością
  atrybutu <verb class="attr">master-reference</verb>.  Element ten jest typowo
  wykorzystywany do definiowania stron tytułowych.
</para>
</descr>
</descritem>
<descritem>
<term><verb class="xslel">fo:repeatable-page-master-reference</verb></term>
<descr>
 <para> 
  deklaracja
  formatowania sekwencji stron przy wykorzystaniu identycznego układu
  graficznego (tj. tego samego SPM).  Liczba stron może być określona
  za pomocą wartości atrybutu <verb class="attr">maximum-repeats</verb>. Brak atrybutu
  lub wartość domyślna równa <verb class="attrval">no-limit</verb> spowoduje
  wygenerowanie tylu stron ile będzie niezbędne do wydrukowania całej
  zawartości bieżącego elementu <verb class="xslel">fo:flow</verb>.
</para>
</descr>
</descritem>
<descritem>
 <term><verb class="xslel">fo:repeatable-page-master-alternatives</verb></term>
 <descr>
  <para>
   Element
   <verb class="xslel">fo:repeatable-page-master-alternatives</verb> jest deklaracją
   formatowania sekwencji stron o <emph>różnych</emph> układach
   graficznych.  Element ten nie posiada atrybutu
   <verb class="attr">master-reference</verb>, ponieważ nie wybiera odpowiedniej strony
   bezpośrednio, ale za pomocą elementów-dzieci
   <verb class="xslel">conditional-page-master-reference</verb> (w skrócie CPMR).
  </para>
 </descr>
</descritem>
</description>
<para>
Każdy CPMR określa warunek, który jeżeli jest spełniony, powoduje
wybranie odpowiedniego SPM. Warunek może określać kolejność strony
w sekwencji stron, numer strony, parzystość-nieparzystość numeru strony 
czy też sprawdzenie czy strona jest pusta, czy też nie.
Warunki są określane za pomocą 
odpowiednich wartości atrybutów <verb class="attr">page-position</verb>, 
<verb class="attr">odd-or-even</verb>, 
<verb class="attr">blank-or-not-blank</verb>:
</para>
<itemize>
 <item>
  <para> 
   Atrybut <verb class="attr">page-position</verb> 
   o wartościach 
   <verb class="attrval">first</verb>
   <verb class="attrval">last</verb>,
   <verb class="attrval">rest</verb>,
   <verb class="attrval">any</verb>
   pozwala na wybranie odpowiednio: pierwszej, ostatniej, wszystkich,
   za wyjątkiem pierwszej i ostatniej oraz każdej strony.
  </para>
 </item>
 <item>
  <para>
   Atrybut <verb class="attr">odd-or-even</verb> 
   o wartościach <verb class="attrval">odd</verb>,
   <verb class="attrval">even</verb>, <verb class="attrval">any</verb>
   pozwala na wybranie odpowiednio: nieparzystej, 
   parzystej oraz każdej strony.
  </para>
 </item>
 <item>
  <para>
   Atrybut <verb class="attr">blank-or-not-blank</verb> 
   o wartościach <verb class="attrval">blank</verb>,
   <verb class="attrval">not-blank</verb>,
   <verb class="attrval">any</verb> pozwala na wybranie odpowiednio:
   pustej, niepustej oraz każdej strony.
  </para>
 </item>
</itemize>
<para>
Najczęściej spotykany układ graficzny dokumentu składa się z kolumn
trzech rodzajów: tytułowej, lewej i prawej (rys <ref src="pic-uklady"/>).  
Oto prosty przykład szkieletu szablonu określającego 
taki układ (symbol <verb>@@@...</verb> oznacza pominięte -- na tym etapie
opisu -- definicje atrybutów określających wymiary, marginesy, 
ramki, kolory itp. elementy układu graficznego):
</para>
<figure id="pic-uklady">
<title>Szkielet układu graficznego stronic: 
 tytułowej, parzystej i nieparzystej</title>
 <graphic format="EPS" src="pages.eps"/>
 <graphic format="JPG" src="pages.jpg"/>
 <graphic format="PNG" src="pages.png"/>
</figure>

<verbatim>
&lt;fo:layout-master-set>
&lt;!-- definiujemy trzy makiety: tytułowa, lewa i prawa -->
  &lt;fo:simple-page-master master-name="tytulowa" @@@...>
    &lt;fo:region-body @@@... />
    &lt;fo:region-after region-name="tytulowa-p.dolna" @@@... />
    &lt;fo:region-before region-name="tytulowa-p.gorna" @@@... />
  &lt;/fo:simple-page-master>

&lt;!-- definiujemy poszczególne fragmenty na stronach -->
  &lt;fo:simple-page-master master-name="lewa" @@@... >
    &lt;fo:region-body @@@... />
    &lt;fo:region-after region-name="lewa-p.dolna" @@@... />
    &lt;fo:region-before region-name="lewa-p.gorna" @@@... />
  &lt;/fo:simple-page-master>

  &lt;fo:simple-page-master master-name="prawa" @@@... >
    &lt;fo:region-body @@@... />
    &lt;fo:region-after region-name="prawa-p.dolna" @@@... />
    &lt;fo:region-before region-name="prawa-p.gorna" @@@... />
  &lt;/fo:simple-page-master>

&lt;!-- określamy układ dwustronny: -->
  &lt;fo:page-sequence-master master-name="d-stronny">
    &lt;fo:repeatable-page-master-alternatives>
      &lt;fo:conditional-page-master-reference master-reference="tytulowa" page-position="first" />
      &lt;fo:conditional-page-master-reference master-reference="prawa" odd-or-even="odd" />
      &lt;fo:conditional-page-master-reference master-reference="lewa" odd-or-even="even" />
    &lt;/fo:repeatable-page-master-alternatives>
  &lt;/fo:page-sequence-master>

&lt;!-- określamy układ jednostronny (z wyróżnioną str. tyt.): -->
  &lt;fo:page-sequence-master master-name="j-stronny">
    &lt;fo:repeatable-page-master-alternatives>
      &lt;fo:conditional-page-master-reference master-reference="tytulowa" page-position="first" />
      &lt;fo:conditional-page-master-reference master-reference="prawa" />
    &lt;/fo:repeatable-page-master-alternatives>
  &lt;/fo:page-sequence-master>
&lt;/fo:layout-master-set>
</verbatim>
<para>
Treść formatowanego dokumentu znajduje się wewnątrz elementu
<verb class="xslel">fo:page-sequence</verb>. Układ graficzny kolumny tekstu jest określony
poprzez skojarzenie tegoż elementu z odpowiednim SPM lub PSM za pomocą
identycznej wartości 
atrybutów 
<verb class="attr">master-reference</verb>/<verb class="attr">master-name</verb>.
</para>
<para>
Zawartością <verb class="xslel">fo:page-sequence</verb>
jest opcjonalny element <verb class="xslel">fo:title</verb>, zero lub więcej
elementów <verb class="xslel">fo:static-content</verb> oraz dokładnie jeden element
<verb class="xslel">fo:flow</verb>. 
</para>
<para>
Elementy <verb class="xslel">fo:static-content</verb> służą typowo do określania
zawartości pagin i marginaliów. Wartość atrybutu
<verb class="attrval">flow-name</verb><footnote>Odpowiadająca wartości atrybutu
  <verb class="attrval">region-name</verb> elementów 
<verb class="xslel">region-...</verb>.</footnote>  identyfikuje
obszar, w którym zostanie umieszczony dany element
<verb class="xslel">fo:static-content</verb>.
</para>
<para>
Ilustracją tego, co powiedziano w poprzednich trzech akapitach,
może być następujący fragment szablonu (symbol 
<verb>###...</verb> oznacza pominiętą -- w imię zwięzłości
opisu -- zawartość elementów <verb class="xslel">static-content</verb>
oraz <verb class="xslel">flow</verb>):
</para>
<verbatim>
 &lt;fo:page-sequence master-reference="d-stronny">
  &lt;fo:static-content flow-name="prawa-p.dolna"> ###...  &lt;/fo:static-content>
  &lt;fo:static-content flow-name="lewa-p.dolna"> ###... &lt;/fo:static-content>
  &lt;fo:static-content flow-name="prawa-p.gorna"> ###... &lt;/fo:static-content>
  &lt;fo:static-content flow-name="lewa-p.gorna"> ###...  &lt;/fo:static-content>
  &lt;fo:static-content flow-name="tytulowa-p.dolna" > ###... &lt;/fo:static-content>
  &lt;fo:static-content flow-name="tytulowa-p.gorna"> ###... &lt;/fo:static-content>

  &lt;fo:flow flow-name="xsl-region-body"> ###... &lt;fo:flow>
 &lt;/fo:page-sequence>
&lt;/fo:root>
</verbatim>
</section>
<section id="sec-details">
<title>Określenie szczegółów układu graficznego kolumn</title>
<para>
W tym punkcie omówimy w jaki sposób określić wygląd poszczególnych
obszarów stronicy zdefiniowanych w punkcie poprzednim.
Wielkość strony jest określona za pomocą atrybutów <verb class="attr">page-height</verb>
oraz <verb class="attr">page-width</verb> elementu <verb class="xslel">fo:simple-page-master</verb>.
Wymiary kolumny tekstu są określone pośrednio 
jako różnica pomiędzy wymiarami strony a wielkością odpowiednich 
marginesów (określonych za pomocą atrybutów:
<verb class="attr">margin-left</verb>, <verb class="attr">margin-right</verb>, <verb class="attr">margin-top</verb>,
<verb class="attr">margin-bottom</verb>). Przykładowo:
</para>
<verbatim>
&lt;fo:simple-page-master master-name="tytulowa" page-width='210mm' page-height='297mm' />
&lt;fo:region-body margin-left='30mm' margin-right='20mm' margin-top='20mm' margin-bottom='30mm'/>
</verbatim>
<para>
W przypadku atrybutu <verb class="attr">margin</verb> (i w wielu innych
miejscach) możliwe jest przypisanie wszystkim
marginesom, tj. <verb class="attr">margin-top</verb>, <verb class="attr">margin-bottom</verb>,
<verb class="attr">margin-left</verb> i <verb class="attr">margin-right</verb> 
tej samej wartości za pomocą <emph>skrótu</emph> 
<verb class="literal">margin='1in'</verb>. 
Zapis <verb class="literal">margin='1in 1.5in 1in 0.5in'</verb> 
jest przykładem innego
rodzaju skrótu, pozwalającego przypisać różne wartości marginesów.
</para>
<para>
Uwaga:
nie wszystkie procesory &XSLFO; poprawnie 
interpretują skróty, lepiej z nich nie korzystać.
</para>
<para>
Pozostałe obszary przylegają do odpowiednich
krawędzi <emph>strony</emph> a ich wielkość (wysokość dla pagin i szerokość
dla marginaliów) określa atrybut <verb class="attr">extent</verb>.
Wielkość pagin/marginaliów nie ma wpływu na wielkość kolumny głównej.
Innymi słowy margines określony dla 
obszaru <verb class="xslel">region-body</verb> musi
być na tyle duży żeby to co ma być umieszczone w paginach lub na
marginesach nie znalazło się poza 
kartką (nie mniej niż wielkość <verb class="attr">extent</verb>). Przykład:
</para>
<verbatim>
  &lt;fo:region-before region-name="tytulowa-p.gorna" extent="6mm" />
  &lt;fo:region-after region-name="tytulowa-p.dolna" extent="6mm" />
</verbatim>
<para>
Zdefiniowaną w ww. sposób stronicę przedstawia schematycznie 
rys <ref src="pic-kol-wymiary"/>a). Jak widać, położenie paginy nie jest
prawidłowe: jest ona umieszczona zbyt wysoko nad kolumną tekstu,
a jej szerokość jest równa 
szerokości stronicy.
</para>

<figure id ="pic-kol-wymiary">
 <title>Wymiary kolumny głównej i paginy górnej</title>
 <graphic format="EPS" src="kol-wym.eps"/>
 <graphic format="JPG" src="kol-wym.jpg"/>
</figure>
<para>
Dla wszystkich obszarów można określić <emph>obramowanie</emph> (<emph>border</emph>),
<emph>marginesy wewnętrzne</emph> (<emph>padding</emph>) oraz <emph>kolor tła</emph>.
Możliwe jest określenie następujących właściwości obramowania: 
<emph>kolor</emph>
(16 kolorów predefiniowanych w specyfikacji HTML lub wartość RGB koloru),
<emph>rodzaj ramki</emph> (linia ciągła, kreski, kropki itp...),
<emph>szerokość</emph> (predefiniowane wartości <verb class="literal">thin</verb>,
<verb class="literal">medium</verb>, <verb class="literal">thick</verb> lub jawnie podany
wymiar, np. <verb class="literal">3pt</verb>).
</para>
<para>
Każda właściwość obramowania może być zdefiniowana dla każdej krawędzi 
obszaru odzielnie za pomocą atrybutu o postaci:
<verb class="attr">border-krawędź-właściwość</verb>. Przykład:
</para>

<verbatim>
&lt;fo:region-before         
     border-top-color="C0C0C0" border-top-style="solid" border-top-width="1.5pt" />
</verbatim>
<para>
Używając skrótu <verb class="attr">border-właściwość</verb> można zdefiniować
każdą właściwość dla czterech krawędzi łącznie. 
Podobnie, odpowiednio określając  wartość atrybutu 
postaci <verb class="attr">border-krawędź</verb>, można określić łącznie
wiele właściwości dla pojedynczej krawędzi.
Wreszcie pojedynczy atrybut <verb class="attr">border</verb> pozwala na łączne określenie
wielu właściwości dla wszystkich krawędzi.
Przykład:
</para>
<verbatim>
&lt;fo:region-before border-color="C0C0C0" border-style="solid" border-width="1.5pt" />
&lt;fo:region-after border-bottom="C0C0C0 solid 1.5pt" />
&lt;fo:region-end border=""
</verbatim>
<para>
Uwaga: kolejność poszczególnych właściwości w definicji atrybutu
<verb class="attr">border-krawędź</verb> 
i <verb class="attr">border</verb> jest dowolna.  [Nie wszystkie procesory
&XSLFO; poprawnie interpretują skróty.]
</para>
<para>
Margines wewnętrzny jest definiowany za pomocą atrybutu
<verb class="attrval">padding-krawędź</verb>, który może zostać skrócony
do postaci <verb class="attrval">padding</verb><footnote>Określa wtedy margines wewnętrzny 
dla wielu wartości. [Nie jest interpretowany przez 
wszystkie procesory:-)].</footnote>. Przykład:
</para>
<verbatim>
&lt;fo:region-before padding-befor="24pt" />
&lt;fo:region-after padding="24pt" />
&lt;fo:region-end padding="1cm 3cm"/>     &lt;!-- góra/dół=1cm, lewy/prawy=3cm      -->
&lt;fo:region-end padding="1cm 2cm 3cm"/> &lt;!-- góra=1cm, lewy/prawy=2cm, dół=3cm -->
</verbatim>
<para>
Jeżeli wartość <verb class="attr">padding</verb> zawiera dwa wymiary to pierwszy określa wartość
marginesu wewnętrznego dla krawędzi górnej i dolnej,
a druga dla prawej i lewej.
Jeżeli zawiera trzy wymiary, to pierwszy 
określa margines górny, druga marginesy prawy i lewy 
a trzecia margines dolny. Cztery wartości określają 
kolejno wielkość marginesu:
górnego, prawego, dolnego i lewego. Jedna wartość określa wspólną wielkość
marginesu dla wszystkich  
krawędzi łącznie.
</para>
<para>
Dla każdego obszaru można także zdefiniować kolor tła używając
atrybutu: <verb class="attr">background-color</verb>. Specyfikacja wartości jest identyczna
jak w przypadku koloru obramowania.
</para>
<para>
Z powyższych rozważań wynika, że odpowiednio 
ustawiając margines wewnętrzny dla 
obszaru odpowiadającego paginie górnej można osiągnąć efekt przedstawiony
schematycznie na rys. <ref src="pic-kol-wymiary"/>b):
</para>
<verbatim>
  &lt;fo:region-before region-name="tytulowa-p.gorna" extent="20mm" 
       padding-before="14mm" padding-start="30mm" />
</verbatim>
<para>
Brakuje jeszcze tylko kreski oddzielającej zwykle paginę od tekstu
głównego. Dodając obramowanie i niezbędne marginesy wewnętrzne:
</para>
<verbatim>
  &lt;fo:region-body margin="20mm 20mm 30mm 30mm" padding-top="4mm" />
  &lt;fo:region-before region-name="tytulowa-p.gorna" extent="20mm" 
      border-width=".4pt" border-color="black" border-style="solid"
      padding-before="14mm" padding-start="30mm" />
</verbatim>
<para>
osiągniemy wreszcie zadowalający efekt przedstawiony 
na rys. <ref src="pic-kol-wymiary"/> c).
</para>
</section>
<section>
<title>Formatowanie tekstu</title>
<para>
Przypomnijmy (por. rys. <ref src="pic-fo-struct"/>), 
że treść dokumentu jest umieszczana wewnątrz elementów
<verb class="xslel">fo:flow</verb>
lub <verb class="xslel">fo:static-content</verb> (elementy te są dziećmi
<verb class="xslel">fo:page-sequence</verb>).
Z tym, że treść <emph>nie może</emph> być
umieszczona bezpośrednio wewnątrz nich ale powinna być ,,opakowana''
za pomocą takich elementów, jak: <verb class="xslel">fo:block</verb>,
<verb class="xslel">fo:list-block</verb>
oraz <verb class="xslel">fo:float</verb> i kilku innych.
Poszczególne akapity, śródtytuły i podobne elementy
są umieszczane wewnątrz
<verb class="xslel">fo:block</verb>,
wyliczenia i wypunktowania wewnątrz
<verb class="xslel">fo:list-block</verb>,
tabele wewnątrz <verb class="xslel">fo:table</verb> lub
<verb class="xslel">fo:table-and-caption</verb>.  Konkretny wygląd graficzny określają
odpowiednie atrybuty w sposób podobny, jak w przypadku elementów
definiujących obszary.
</para>
<subsection id="ssec-blocks">
<title>Bloki tekstu: odstępy i marginesy </title>
<para>
Elementy <verb class="xslel">fo:block</verb> to zwykle akapity i śródtytuły.  Tego typu
elementy umieszczane jeden pod drugim składają się na zawartość
kolejnych stron dokumentu.  Poszczególne bloki tekstu mogą zostać
oddzielone odstępem przy wykorzystaniu opisanych wyżej atrybutów typu
<emph>margin</emph>. Ustalanie zwłaszcza odstępu pomiędzy blokami za
pomocą tych atrybutów nie jest jednak wskazane. Do tego celu lepiej
wykorzystać atrybuty <verb class="attr">space-before</verb> 
i <verb class="attr">space-after</verb><footnote>
  Uwaga: atrybuty określające odstępy ,,poziome'': <verb class="attr">space-start</verb>
  oraz <verb class="attr">space-end</verb> nie dotyczą bloków ale obiektów wewnątrz
  bloków (<emph>inline objects</emph>).</footnote>.
</para>
<para>
Różne traktowanie obszarów i bloków, które na pierwszy rzut oka są tym
samym obiektem (prostokątem), wynika z tego, że sposób wstawiania
odstępów pomiędzy bloki tekstu powinien uwzględniać dodatkowo takie
detale, jak np.  domyślne usuwanie odstępu na dole/górze strony, oraz
,,inteligentne'' scalanie sąsiadujących odstępów w jeden.
</para>
<para>
Przykładowo: odstęp pomiędzy akapitami winien zwykle znikać jeżeli
akapit jest pierwszym na stronie aby wysokości stron sąsiadujących
były jednakowe.
</para>
<para>
Także odstępy pomiędzy różnymi blokami tekstu nie powinny się zwykle
sumować.  Przykładem jest umieszczanie większych niż normalne odstępów
przed i po śródtytułach<footnote>
  Załóżmy, że zakładamy odstęp wielkości np. 24 punkty przed oraz 12
  punktów po śródtytule pierwszego stopnia, 12 punktów przed, oraz
  6 punktów po śródtytule drugiego stopnia i 1,5 punktów przed i po
  akapicie. Wówczas odstęp pomiędzy śródtytułami będzie wynosił 12 +
  12 = 24 punkty; a odstęp pomiędzy śródtytułem pierwszego stopnia
  a tekstem tylko 1,5 + 12 = 13,5 punkty. W tej sytuacji tylko jeden
  z odstępów powinien być zachowany.</footnote>.
</para>
<para>
Przypisanie atrybutom
<verb class="attr">space-before.przyrostek</verb> oraz
<verb class="attr">space-after.przyrostek</verb>
odpowiednich wartości
pozwala na rozwiązanie ww. problemów.  
Atrybut <verb class="attr">space-before.optimum</verb>
określa naturalny odstęp pomiędzy blokami, <verb class="attr">space-before.minimum</verb>
minimalny a <verb class="attr">space-before.maximum</verb> -- maksymalny. Zatem
odpowiednikiem LaTeXowego
polecenia <verb>\vspace{6mm plus 3mm minus 1.5mm}</verb> będzie:
</para>
<verbatim>
&lt;fo:block space-before.optimum='6mm' space-before.minimum='4.5mm'
    space-before.maximum='7.5mm'>
</verbatim>
<para>
Atrybut <verb class="attr">space-before.przyrostek</verb> jest
przykładem tzw. <emph>atrybutu złożonego</emph>, 
którego nazwa składa się
z części zasadniczej, takiej jak np.  <verb class="attr">space-before</verb> oraz
oddzielonego kropką przyrostka, np. <verb class="attr">optimum</verb>.
W standardzie &XSLFO; zdefiniowanych jest więcej tego typu atrybutów.
</para>
<para>
Domyślnie sąsiadujące odstępy nie są sumowane ale zastępowane jednym,
zwykle większym, choć reguły określone w specyfikacji <cite src="FO"/>
są bardziej skomplikowane. Do bardziej szczegółowego
określenie sposobu ustalania odstępów należy użyć odpowiedniego atrybutu 
z przyrostkiem <verb class="attr">precedence</verb>, którego wartością może być liczba 
lub specjalna wartość <verb class="attrval">force</verb>, określająca <emph>priorytet</emph>. 
Odstępy pomiędzy sąsiadującymi z sobą blokami tekstu są łączone 
w oparciu o wartość nadanego im priorytetu. Odstępy z przydzieloną najwyższą
wartością są pozostawiane, a pozostałe usuwane. 
Wartość atrybutu <verb class="attrval">force</verb> powoduje, że odstęp jest 
zachowywany bezwzględnie. Przykład:
</para>
<verbatim>
&lt;fo:block space-after='18pt' space-after.precedence='1'>Tytuł&lt;/fo:block>
&lt;fo:block space-before='3pt'>Pierwszy akapit...&lt;/fo:block>
</verbatim>
<para>
W powyższym przykładzie zostanie wstawiony odstęp o większym
priorytecie, tj. 18pt po pierwszym bloku tekstu, zaś odstęp 3pt przed
drugim blokiem zniknie. Atrybut postaci <verb class="attr">space-after</verb> jest
skrótem; jeżeli jego wartością jest pojedynczy odstęp, to oznacza
to przypisanie odstępowi (naturalnemu, minimalnemu
i maksymalnemu) tej samej wartości.
</para>
<para>
Przyrostek <verb class="attr">.conditionality</verb> określa czy odstęp ma zostać
usunięty (domyślnie odpowiada wartości atrybutu <verb class="attrval">discard</verb>)
czy pozostawiony (<verb class="attrval">retain</verb>), jeżeli blok będzie pierwszym lub
ostatnim blokiem wewnątrz innego bloku lub na stronie.
</para>
<para>
Bloki tekstu mogą zostać wcięte w stosunku do otaczającego je bloku
lub strony poprzez wykorzystanie atrybutu <verb class="attr">start-indent</verb> oraz
<verb class="attr">end-indent</verb>. 
Ten sam efekt można osiągnąć korzystając
z atrybutów <verb class="attr">left-margin</verb> oraz <verb class="attr">rigth-margin</verb>.
</para>
<para>
W czasie podziału dokumentu na strony blok może zostać podzielony
jeżeli nie może być zmieszczony na bieżącej stronicy (łamie). Także w tym
przypadku istnieją różne ograniczenia wynikające z tradycji,
zwyczajów drukarskich i wydawniczych.  Przykładowo powszechnie
nieakceptowane jest łamanie stron, w którym śródtytuły są ostatnimi
elementami na stronie; wielu wydawców nie akceptuje także sytuacji,
w której ostatni wiersz akapitu zaczyna stronę lub pierwszy wiersz
akapitu stronę kończy. 
Oczywiste jest także, że np.: śródtytuły nie 
mogą znajdować się bezpośrednio na dole strony, ani też wielowierszowe 
śródtytuły nie mogą być podzielone pomiędzy stronice.
</para>
<para>
Atrybut <verb class="attr">keep-together.przyrostek</verb>
określa czy blok <emph>może</emph> zostać podzielony
w czasie stronicowania dokumentu. Wartością atrybutu może być:
<verb class="attrval">auto</verb> (może być podzielony), 
<verb class="attrval">always</verb> (nie może być nigdy podzielony)
lub liczba określająca stan pośredni.
Dodanie przyrostka <verb class="attrval">.within-page</verb> zakazuje podziału
bloku pomiędzy stronice, podczas gdy <verb class="attrval">.within-columns</verb> 
dotyczy
kolumn w składzie wielołamowym.
</para>
<para>
Atrybut <verb class="attr">keep-with-previous.przyrostek</verb> 
określa czy bieżący blok musi znajdować się na tej samej 
stronie (z przyrostkiem <verb class="attr">.within-page</verb>) lub
łamie (<verb class="attr">.within-column</verb>) co blok poprzedni. Zbiór możliwych
wartości atrybutu to: 
<verb class="attrval">auto</verb> (nie musi), <verb class="attrval">always</verb> (musi)
lub liczba (określa stan pośredni pomiędzy <verb class="attrval">auto</verb>
i <verb class="attrval">always</verb>).
Odwrotnością <verb class="attr">keep-with-previous</verb> jest 
atrybut <verb class="attr">break-before</verb>, którego zbiorem wartości jest:
<verb class="attrval">auto</verb>, <verb class="attrval">column</verb>, <verb class="attrval">page</verb>
<verb class="attrval">odd-page</verb> <verb class="attrval">even-page</verb>. 
Wartości te oznaczają odpowiednio: rozpoczęcie nowego łamu,
nowej stronicy, stronicy nieparzystej 
i stronicy parzystej.
</para>
<para>
Można także określić minimalną liczbę wierszy na końcu
lub na początku kolumny za pomocą przypisania 
atrybutom <verb class="attr">orphans</verb> oraz <verb class="attr">widows</verb> odpowiedniej liczby. 
Domyślną wartością obu atrybutów jest 2.
</para>
<para>
Bloki mogą posiadać <emph>obramowanie</emph>, <emph>marginesy
  wewnętrzne</emph> i <emph>kolor tła</emph>, specyfikowane identycznie jak
w przypadku obszarów.  W przeciwieństwie do obszaru blok może zostać
podzielony pomiędzy sąsiadujące stronice lub łamy. W tej sytuacji 
możliwe jest określenie sposobu obramowania brzegu
obszaru przylegającego do krawędzi podziału bloku.  Wartość
<verb class="attrval">discard</verb> atrybutu
<verb class="attr">border-krawędź</verb><footnote>Dopuszczalne wartości to
  wyłącznie: <verb class="attr">before</verb>, 
 <verb class="attr">after</verb>, 
 <verb class="attr">start</verb>,
 <!-- ???? Tu jest jakiś problem -->
 <verb class="attr">end</verb>.</footnote>-<verb 
 class="attr">width</verb>.<verb class="attr">conditionality</verb> 
zawiesza drukowanie ramki. 
Domyślnie ramka jest drukowana.
</para>
</subsection>
<subsection>
<title>Interlinia, justowanie tekstu, wcięcia akapitowe</title>
<para>
Atrybut <verb class="attr">line-height</verb> określa wielkość
interlinii, która może być określona w wartościach bezwzględnych jako
liczba bądź wartość procentowa.  Liczby i procenty są interpretowane
jako krotności bieżącego stopnia pisma.  Atrybut 
<verb class="attr">text-align</verb> określa sposób justowania tekstu;
dopuszczalne wartości to: <verb class="attrval">left</verb>, 
<verb class="attrval">right</verb>, <verb class="attrval">center</verb>
i <verb class="attrval">justify</verb>.  Wielkość wcięcia akapitowego
określa atrybut <verb class="attr">text-indent</verb>.  Sposób
justowania ostatniego wiersza akapitu określa 
atrybut <verb class="attr">text-align-last</verb> opisany 
w punkcie <ref src="sec-page-numbers"/>.  
Wcięcie ostatniego wiersza (od prawej
strony) można określić za pomocą odpowiedniej wartości atrybutu 
<verb class="attr">last-line-end-indent</verb>.
</para>
<para>
Atrybut <verb class="attr">hyphenate</verb> 
określa, czy wyrazy mogą (wartość
<verb class="attrval">true</verb>) 
czy nie mogą (wartość <verb class="attrval">false</verb>) być przenoszone
w procesie podziału akapitu na wiersze.
Standard umożliwia
dokładniejsze określenie sposobu przenoszenia.
Przykładowo, atrybut <verb class="attr">hyphenation-character</verb> określa znak
przeniesienia (wartość początkowa to znak 
o numerze <verb class="attrval">U+2010</verb> (Unicode),
czyli ,,<verb class="attrval">-</verb>''). 
</para>
<para>
Za pomocą określenia odpowiedniej wartości atrybutu
<verb class="attr">hyphenation-keep</verb> elementu <verb class="xslel">fo:block</verb> 
można kontrolować przenoszenie wyrazów pomiędzy szpaltami
i/lub stronami. W szczególności wartość <verb class="attrval">column</verb> tego atrybutu
określa, że wyraz nie może być podzielony pomiędzy kolejnymi
szpalatami tekstu, podczas gdy wartość <verb class="attrval">page</verb> jest
nieco mniej restrykcyjna i zabrania jedynie dzielenia
wyrazów pomiędzy kolejne stronice.
Wreszcie 
atrybut <verb class="attr">hyphenation-ladder-count</verb> określa maksymalną dopuszczalną
liczbę kolejnych przeniesień.
</para>
<para>
Atrybuty <verb class="attr">hyphenation-remain-character-count</verb> oraz
<verb class="attr">hyphenation-push-character-count</verb> umożliwiają określenie
minimalnej liczby znaków w obu częściach podzielonego słowa.
</para>
</subsection>

<subsection id="ssec-fonts">
<title>Określenie kroju pisma i koloru</title>
<para>
Atrybuty <verb class="attr">font-family</verb>, <verb class="attr">font-size</verb>, <verb class="attr">font-style</verb>,
<verb class="attr">font-variant</verb>, <verb class="attr">font-weight</verb> pozwalają na określenie
kroju, stopnia i odmiany pisma. 
Wartością atrybutu <verb class="attr">font-family</verb> jest lista oddzielonych
przecinkami nazw krojów lub typów krojów.
Typ kroju to <verb class="attrval">serif</verb>, <verb class="attrval">sans-serif</verb>, 
<verb class="attrval">cursive</verb>, <verb class="attrval">fantasy</verb> oraz
<verb class="attrval">monospace</verb>. Do formatowania dokumentu wybrany zostanie
pierwszy krój z listy dostępnych podczas formatowania, np:
</para>
<verbatim>
&lt;fo:block font-family='Bembo, Times, serif' >
</verbatim>
<para>
spowoduje wybranie kroju <verb class="attrval">Bembo</verb> lub <verb class="attrval">Times</verb> lub
domyślnego kroju szeryfowego w zależności od tego, czym dysponuje
program formatujący dokument.
</para>
<para>
Wartością atrybutu <verb class="attr">font-size</verb> może być wymiar, np. <verb class="attrval">12pt</verb>.
Wielkość kroju  można także określić względnie
w stosunku do stopnia pisma w elemencie nadrzędnym albo
poprzez podanie jednej z wartości <verb class="attrval">larger</verb> lub <verb class="attrval">smaller</verb>,
albo poprzez podanie procentu. Możliwe jest
wreszcie określenie stopnia za pomocą wartości <verb class="attrval">xx-small</verb>,
<verb class="attrval">x-small</verb> <verb class="attrval">small</verb>, <verb class="attrval">medium</verb> <verb class="attrval">large</verb>,
<verb class="attrval">x-large</verb> <verb class="attrval">xx-large</verb>.
</para>
<para>
Atrybuty  <verb class="attr">font-style</verb>, <verb class="attr">font-variant</verb>, <verb class="attr">font-weight</verb>
służą do określenia odmiany pisma.
Wartościami atrybutu <verb class="attr">font-style</verb> mogą być:
<verb class="attrval">normal</verb> -- odmiana prosta,
<verb class="attrval">oblique</verb> -- odmiana pochyła,
<verb class="attrval">italic</verb> -- kursywa. 
Atrybut <verb class="attr">font-variant</verb> ma następujące wartości: 
<verb class="attrval">normal</verb> -- odmiana zwykła oraz <verb class="attrval">small-caps</verb> 
-- kapitaliki. Wreszcie atrybut <verb class="attr">font-weight</verb> określa
grubość pisma i może przyjąć następujące wartości:
<verb class="attrval">normal</verb> -- pismo zwykłe,
<verb class="attrval">bold</verb> i <verb class="attrval">bolder</verb> -- grube,
<verb class="attrval">lighter</verb> -- cienkie
lub liczbę od 100, 200, 300 itd. aż do wartości maksymalnej 900.
</para>
<para>
Uwaga:
atrybuty określające krój pisma mogą zostać wyspecyfikowane dla każdego
elementu w arkuszu &XSLFO;, nie tylko <verb class="xslel">fo:block</verb>. 
Przykładowo:
<verb>&lt;fo:root font-family='Univers'></verb>
określa, że dokument ma zostać złożony za pomocą kroju Univers.
</para>
<para>
Możliwe jest także wykorzystanie notacji skrótowej, a wtedy
składnia atrybutu <verb class="attr">font</verb> jest następująca:
</para>
<verbatim>
[font-style [font-weight][font-variant]] font-size[line-height] font-family
</verbatim>
<para>
Fragmenty zawarte pomiędzy <verb>[]</verb> są opcjonalne. Atrybuty pominięte 
nie są dziedziczone lecz przyjmują wartości 
domyślne, co może być pewnym zaskoczeniem 
jeżeli się o tym nie wie.
</para>
<para>
Atrybut <verb class="attr">color</verb> określa koloru tekstu. Wartość tego atrybutu
można określić w sposób identyczny jak w przypadku 
koloru obramowania (por. punkt <ref src="sec-details"/>).
</para>
<para>
Przykładem opisanych w punktach <ref src="ssec-blocks"/>--<ref src="ssec-fonts"/>
właściwości niech będzie następujący fragment szablonu:
</para>
<verbatim>
&lt;!-- Blok tekstu zawierający śródtytuł  -->
&lt;fo:block font-size="14pt" color="#0060A0" font-weight="bold"
  keep-together.within-column="always"  &lt;!-- nie dzielić bloku między łamy -->
  keep-with-next.within-column=always"  &lt;!-- blok nie może kończyć łamu -->
  text-align="left" hyphenate="false"   &lt;!-- skład w chorągiewkę, bez przenoszenia wyrazów -->
  space-before.conditionality="discard" &lt;!-- usuń poniższy odstęp jeżeli zaczyna stronicę -->
  space-before.optimum="18pt" space-after.optimum="6pt" >
  ###...
&lt;/fo:block>
&lt;!-- Blok tekstu składany literalnie (tj. verbatim): -->
  &lt;fo:block font-family="monospace" font-size="9.5pt"
     text-align="left" space-before="6pt" space-after="6pt"
     white-space-collapse="false" linefeed-treatment="preserve" 
     border="0.5pt gray solid" padding="3pt" &lt;!-- ramka wokół tekstu -->
     border-before-width.conditionality="discard" &lt;!-- usuń ramkę na dole strony -->
     border-after-width.conditionality="discard"  &lt;!-- oraz na górze -->
       orphans="3" widows="3" >
  ###...
&lt;/fo:block>
</verbatim>
<para>
W specyfikacji bloku tekstu składanego literalnie określono m.in., że ma być 
on otoczona obramowaniem w kolorze szarym, które ma zniknąć
na brzegach stronic, jeżeli blok zostanie pomiędzy nie podzielony.
</para>
<para>
Element <verb class="xslel">fo:wrapper</verb> jest opakowaniem na fragment tekstu, dla
którego można zadeklarować odrębne atrybuty, takie jak: krój lub
odmianę pisma, itp. Podobny do <verb class="xslel">fo:wrapper</verb> jest element
<verb class="xslel">fo:inline</verb>, dla którego dodatkowo można określić obramowanie,
margines wewnętrzny i tło.  Przykład:
</para>
<verbatim> 
&lt;fo:wrapper font-style="italic">Ten fragment jest wyróżniony... &lt;/fo:wrapper>
&lt;fo:inline font-weight="bold" background-color="red">Na czerwonym tle... &lt;/fo:inline>
</verbatim>
</subsection>
</section>
<section>
<title>Wyliczenia</title>
<para>
Wyliczenie jest formatowane za pomocą elementu 
<verb class="xslel">fo:list-block</verb>, zawierającego
jeden lub więcej elementów <verb class="xslel">fo:list-item</verb>.
Każdy <verb class="xslel">fo:list-item</verb> składa się z <emph>etykiety</emph> 
(zawartej wewnątrz <verb class="xslel">fo:list-item-label</verb>) oraz <emph>hasła</emph>
(<verb class="xslel">fo:list-item-body</verb>).
Oba elementy zawierają bloki, które
są wyrównywane w pionie i umieszczane obok siebie.
Często etykieta to pojedynczy znak lub kolejny numer, ale może być
to także większy fragment tekstu. W tym ostatnim przypadku tekst ten
będzie łamany w obszarze o zadanej szerokości.
</para>
<para>
Atrybut 
<verb class="attrval">provisional-distance-between-starts</verb> 
określa odległość pomiędzy lewą krawędzią
elementu <verb class="literal">item-label</verb> a lewą krawędzią elementu <verb class="literal">item-body</verb>.
Atrybut  <verb class="attrval">provisional-label-separation</verb> określa odległość pomiędzy
prawą krawędzią etykiety a lewą krawędzią hasła. 
Atrybut <verb class="attr">end-indent</verb> elementu <verb class="xslel">fo:list-item-label</verb> 
określa prawą krawędź obszaru,
w którym zostanie umieszczona etykieta, zaś atrybut 
<verb class="attr">start-indent</verb> elementu 
<verb class="xslel">fo:list-item-body</verb> lewą krawędź obszaru, w którym zostanie 
umieszczone hasło (rys. 5).
Aby oba obszary nie zachodziły na siebie, należy ww. atrybutom 
przypisać sensowne
wartości. 
Można je policzyć na kartce i wstawić ,,ręcznie'', a można
skorzystać ze specjalnych wartości: 
<verb class="attrval">label-end()</verb>/<verb class="attrval">body-start()</verb> 
a wtedy obliczenia wykona procesor &XSLFO;. 
Przykład:
</para>
<verbatim>
&lt;fo:list-block provisional-distance-between-starts="20mm"
    provisional-label-separation="4mm">
  &lt;fo:list-item>
    &lt;fo:list-item-label end-indent="label-end()">
      &lt;fo:block background-color="yellow">
       Pierwszy
      &lt;/fo:block>
    &lt;/fo:list-item-label>
    &lt;fo:list-item-body start-indent="body-start()">
       &lt;fo:block>Opis pierwszego punktu...&lt;/fo:block>
    &lt;/fo:list-item-body>
  &lt;/fo:list-item>
  &lt;fo:list-item>
    &lt;fo:list-item-label end-indent="label-end()">
      &lt;fo:block background-color="#EFEFEF">Drugi 
       trzeci czwarty piąty...
      &lt;/fo:block>
    &lt;/fo:list-item-label>
    &lt;fo:list-item-body start-indent="body-start()>
       &lt;fo:block>Opis drugiego punktu, opis
            trzeciego punktu ...
       &lt;/fo:block>
    &lt;/fo:list-item-body>
  &lt;/fo:list-item>
&lt;/fo:list-block>
</verbatim>

<figure id="pic-wylicz">
 <title>Określenie wymiarów elementów wyliczeń</title>
 <graphic format="EPS" src="lists.eps"/>
 <graphic format="JPG" src="lists.jpg"/>
</figure>
</section>

<section>
<title>Pozostałe wybrane elementy</title>
<subsection>
<title>Hiperłącza</title>
<para>
Istnieją dwa typu łączy hipertekstowych: do innych części dokumentu
oraz do obiektów zewnętrznych. W obu wypadkach są one tworzone za
pomocą elementu <verb class="xslel">fo:basic-link</verb>.  Łącza do
innej części dokumentu są definiowane za pomocą nadania atrybutowi
<verb class="attr">internal-destination</verb> wartości identycznej
z tą, którą ma atrybut <verb class="attr">id</verb> elementu, do
którego tworzymy odesłanie. Przykład:
</para>
<verbatim>
Owocnik czubajki kani przedstawia 
&lt;fo:basic-link internal-destination='czubajka'>rys. 3&lt;/fo:basic-link>
</verbatim>
<para>
Łącze zewnętrzne jest definiowane poprzez określenie wartości atrybutu
<verb class="attr">external-destination</verb>. Wartością tego
atrybutu jest URL. Przykład:
</para>
<verbatim>
&lt;fo:basic-link 
external-destination="url('http://www.grzyby.pl/')">www.grzyby.pl&lt;/fo:basic-link>
</verbatim>
<para>
Zwróćmy uwagę na sposób określenia
identyfikatora URL.
</para>
</subsection>
<subsection>
<title>Rysunki</title>
<para>
Ilustracje nie są zwykle częścią pliku &XSLFO; ale są przechowywane
w specyficznych, binarnych formatach i znajdują się w oddzielnych
plikach.  Są dołączane do dokumentu za pomocą elementu
<verb class="xslel">fo:external-graphic</verb>.  Atrybut <verb class="attr">src</verb>, którego wartością
jest identyfikator URI identyfikuje plik z rysunkiem. Rysunek jest
wstawiany w miejscu, w którym znajduje się element
<verb class="xslel">fo:external-graphic</verb>.  Przykład:
</para>
<verbatim>
&lt;fo:block>Zdjęcie czubajki kani: 
 &lt;fo:external-graphic src='url(czubajka.jpg)'>&lt;/fo:block>
</verbatim>
</subsection>
<subsection id="sec-kropkowania">
<title>Kropkowania </title>
<para>
Do tworzenia kropkowania służy element 
<verb class="xslel">fo:leader</verb>. 
Atrybut <verb class="attr">leader-pattern</verb> tego elementu określa sposób
kropkowania.  Wartość <verb class="attrval">space</verb> jest domyślna
i oznacza wypełnienie odstępem.
Wartość <verb class="attrval">rule</verb> oznacza wypełnienie kreską 
zaś <verb class="attrval">dots</verb> oznacza wypełnienie kropkami. Jeżeli
wartością atrybutu jest <verb class="attrval">use-content</verb>, do
wypełnienia kropkowania zostanie użyta zawartość 
elementu <verb class="xslel">fo:leader</verb>.  
Atrybut <verb class="attr">leader-pattern-width</verb> określa wielkość 
odstępu między kropkami zaś atrybuty <verb class="attr">rule-style</verb>
i <verb class="attr">rule-thickness</verb> odpowiednio rodzaj
i grubość kreski (więcej szczegółów zawiera <cite src="FO"/>).
</para>
<para>
Atrybuty <verb class="attr">leader-length.optimum</verb>,
<verb class="attrval">leader-length.minimum</verb>
oraz <verb class="attrval">leader-length.maximum</verb> określają odpowiednio 
naturalna, minimalną oraz maksymalną długość kropkowania.
</para>
</subsection>
<subsection id="sec-page-numbers">
<title>Numery stron</title>
<para>
Do umieszczenia w składzie numeru bieżącej strony należy użyć
elementu <verb class="xslel">fo:page-number</verb>. Zwykle element ten jest
wykorzystywany w paginach i marginaliach.
</para>
<para>
Element <verb class="xslel">page-number-citation</verb> 
wstawia numer strony, na której
znajduje się inny obiekt.  Obiekt ten powinien posiadać atrybut
<verb class="attr">id</verb> 
zaś <verb class="xslel">page-number-citation</verb> 
atrybut <verb class="attr">ref-id</verb>
o identycznych wartościach.
</para>
<para>
Jako przykład wykorzystania elementów opisanych w punktach
<ref src="sec-kropkowania"/>--<ref src="sec-page-numbers"/> zdefiniujmy paginę
górną strony parzystej, tak aby na zewnętrznym marginesie pojawił się
numer strony, a na wewnętrznym tytuł dokumentu, np. <emph>Praktyczne
  wprowadzenie...</emph>:
</para>
<verbatim>
&lt;fo:static-content flow-name="prawa-p.gorna">
 &lt;fo:block font-size="9pt" text-align-last="justify" > Praktyczne wprowadzenie...
   &lt;fo:leader leader-pattern="use-content" /> &lt;fo:page-number /> &lt;/fo:block> 
 &lt;/fo:static-content>
</verbatim>
</subsection>

<subsection>
<title>Przypisy i wstawki</title>
<para>
Element <verb class="xslel">fo:float</verb> jest odpowiednikiem LaTeXowego środowiska
<emph>float</emph>, tj. zawiera niepodzielne elementy, 
które, jeżeli nie mogą być umieszczone w ,,normalnym'' ciągu dokumentu,
mogą być przesunięte na stronę następną. 
</para>
<para>
Elementy
<verb class="xslel">fo:inline</verb> oraz 
<verb class="xslel">fo:footnote-body</verb> 
służą do umieszczenia przypisu na dole stronicy. 
Typowo do sformatowania przypisu,
wewnątrz elementu <verb class="xslel">fo:footnote-body</verb> tworzy się jednoelementowe
wyliczenie. Przykład (numer przypisu
typowo jest wyliczany przez aplikację generującą dokument
<verb class="filename">.fo</verb>, np. procesor &XSLT;):
</para>
<verbatim>
 &lt;fo:footnote> &lt;fo:inline>1&lt;/fo:inline>    
  &lt;fo:footnote-body> &lt;fo:list-block> &lt;fo:list-item>
   &lt;fo:list-item-label end-indent="label-end()">
     &lt;fo:block>1&lt;/fo:block>  
   &lt;/fo:list-item-label>
   &lt;fo:list-item-body start-indent="body-start()">
               ###...
   &lt;/fo:list-item-body>
 &lt;/fo:list-item> &lt;/fo:list-block> &lt;/fo:footnote-body> &lt;/fo:footnote>
</verbatim>
</subsection>
</section>

<section>
<title>Procesor FOP</title>
<para>
Procesor FOP przekształca dokumenty &FO; na pliki PDF. Program jest
napisany w języku Java i rozwijany w ramach <emph>Apache Software
Foundation</emph>. 
Udostępnionej w chwili pisania tego tekstu wersji 0.20.4.
daleko jeszcze do miana oprogramowania produkcyjnej jakości; może
co najwyżej być wykorzystana do eksperymentów lub 
tworzenia prostych dokumentów. 
</para>
<para>
Po pobraniu np. ze strony
<url src="http://xml.apache.org">xml.apache.org</url> 
i rozpakowaniu archiwum <verb>.jar</verb>, program jest gotowy
do użycia<footnote>Wymaga oczywiście uprzedniego zainstalowania
interpretatora języka Java.</footnote>.
Po zainstalowaniu odpowiednich fontów i dodatkowej
nieskomplikowanej konfiguracji umożliwia nawet formatowanie tekstów
w języku polskim.  
</para>
<para>
Do eksperymentów z FOPem wykorzystałem zestaw fontów firmy Microsoft
w formacie TrueType (dostępnych np. 
ze strony <url src="http://www.sourceforge.net/corefonts"/>). FOP
wymaga wygenerowania z pliku <verb class="filename">.ttf</verb> pliku metrycznego
w specyficznym formacie.  Do wygenerowania tego pliku należy
wykorzystać aplikację TTFReader znajdującą 
się w dystrybucji, uruchamiając 
ją w następujący sposób (<verb>$FOPLIBS</verb> zawiera listę ścieżek
do niezbędnych archiwów <verb>.jar</verb>):
</para>
<verbatim>
java -cp $FOPLIBS org.apache.fop.fonts.apps.TTFReader plik.ttf plik.xml
</verbatim>
<para>
Po wygenerowaniu plików metrycznych fonty należy zarejestrować w pliku
konfiguracyjnym znajdującym się 
w <verb>~/conf/userconfig.xml</verb> (<verb>~</verb> oznacza korzeń
instalacji FOPa). Dodanie odpowiedniej informacji powinno być
proste -- można się wzorować na wpisach zawartych w pliku
z dystrybucji.
Aby FOP mógł skorzystać z fontów, musi być uruchomiony z opcją
<verb>-c ścieżka-do-pliku-konfiguracyjnego</verb>, np:
</para>
<verbatim>
fop -c /opt/Jlib/fop/config/userconfig.xml -fo plik.fo -pdf plik.pdf
</verbatim>
<para>
Należy także ,,włączyć'' nasz font dodając 
atrybut <verb class="attr">font-family</verb>,
np. do elementu <verb class="xslel">fo:root</verb>:
</para>
<verbatim>
&lt;fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
   font-family="Times Roman">
</verbatim>
<para>
Jak wspomniano na początku artykułu, typowym sposobem tworzenia plików
PDF jest zamiana pliku &XML; na plik w formacie &FO; za pomocą
arkusza stylu &XSLT;. W przypadku FOPa wymaga to uruchomienia
aplikacji z trzema następującymi parametrami:
</para>
<verbatim>
fop -xml plik.xml -xsl arkusz.xslt -pdf plik.pdf
</verbatim>
<para>
Można także przetworzyć plik <verb class="filename">.fo</verb> bezpośrednio uruchamiając
program z parametrami <verb class="literal">-fo plik.fo -pdf plik.pdf</verb>.
</para>
</section>
<section>
<title>Zakończenie</title>
<para>
Z uwagi na ciągle eksperymentalny charakter aplikacji wspierających
rekomendację &FO; w tym krótkim artykule ograniczyliśmy się
jedynie do podstaw standardu.
Osoby zainteresowane (albo raczej: nie zniechęcone) mogą znaleźć przykładowe
szablony, pliki konfiguracyjne do FOPa i dodatkowe informacje pod
adresem <url src="http://www.gust.org.pl/BIUL/biul18.html"/>.
</para>
</section>
<bibliography>
<bibitem id="Bradley">
Bradley Neil:
<title>The XSL Companion</title>.
Addison-Wesley 2000.
</bibitem>

<bibitem id="FOP">
Dokumentacja procesora FOP, patrz
<url src="http://www.apache.org/fop"/>.
</bibitem>

<bibitem id="Druzdziel">
Druździel Mieczysław, Fijałkowski Tadeusz:
<title>Zecerstwo</title>,
<title>Inwentarium wiedzy o poligrafii</title>,
pod red. Henryka Jankowskiego.
Ossolineum 1988.
</bibitem>

<bibitem id="Kay">
Kay Michael:
<title>&XSLT; Programmer's Reference, 2nd Edition</title>.
Wrox Press Ltd., 2001.
</bibitem>

<bibitem id="JMN">
Nowacki Janusz M.:
<title>TeXnologia a typografia</title>,
Biuletyn GUST 6/1995, s. 3--11. Dokument 
dostępny także w <url src="http://www.gust.org.pl/"/>.
</bibitem>

<bibitem id="Olko">
Olko Mariusz:
<title>XSL -- czyli jak przeczytać &XML;owego ,,Pana Tadeusza''</title>,
Biuletyn GUST 16/2001, s. 25--30.
Dokument dostępny także w <url src="http://www.gust.org.pl/"/>.
</bibitem>

<bibitem id="Pawson">
Pawson Dave:
<title>An introduction to XSL Formatting Objects</title>,
2001. Patrz <url src="http://www.dpawson.co.uk/xsl/sect3/bk/index.html"/>.
</bibitem>

<bibitem id="XSLT">
World Wide Web Consortium:
<title>&XSL; Transformations (&XSLT;)</title>,
patrz <url src="http://www.w3.org/TR/xslt.html"/>.
</bibitem>

<bibitem id="FO">
World Wide Web Consortium:
<title>Extensible Stylesheet Language (XSL)</title>,
patrz <url src="http://www.w3.org/TR/xsl/"/>.
</bibitem>

<bibitem id="XPATH">
World Wide Web Consortium,
<title>&XML; Path Language (XPath)</title>,
patrz <url src="http://www.w3.org/TR/xpath.html"/>.
</bibitem>
</bibliography>
</article>

