Tutorial de Formatting Objects
Versión: 1.0, Enero, 2001

Autor: Victor Manuel Rivas Santos
Web: http://wwwdi.ujaen.es/~vrivas, Mail: vrivas@ujaen.es
inicioGeNeuracursos

(C) GeNeura Team
Web: http://www.geneura.org, Mail: todos@geneura.ugr.es

1. Introducción

Qué es y para qué sirve

Como ya es conocido, la gran ventaja de describir datos en formato XML es que posteriormente pueden ser renderizados y ser visualizados de múltiples formas, como por ejemplo documentos HTML o WML. Existe un tipo de renderización más rígida que la que implican estos formatos, y es la utilizada por procesadores de texto o por ciertos formatos qu ep ermiten especificar cómo debe ser visualizaada la página una vez impresa para el usuario (entiéndase PDF o PostScript).

Formatting Objects (FO) son una implementación específica de un determinado XSLT, y aplicados a un fichero XML nos proporcionan otro fichero con la información de éste renderizada a algún formato de visualización impresa. Esta es quizá la principal diferencia entre un FO y otros XSLT: ambos transforman un documento XML en otro documento XML, pero FO está pensado para generar directamente una renderización.

Formatting Objects y Propiedades

Formatting Objects

Existen actualmente 56 FO, la mayoría de los cuales hacen referencia a distintos tipos de áreas rectangulares, y los que no, son contenedores de áreas rectangulares y espacios vacíos.

Por orden alfabético, estos son los distintos FO (se señalan los aún no implementados):

basic-link (SI) bidi-override (NO) block (SI) block-container (NO)
character (SI) color-profile (NO) conditional-page-master-reference (SI) declarations (NO)
external-graphic (SI) float (NO) flow (SI) footnote (NO)
footnote-body (NO) initial-property-set (NO) inline (SI) inline-container (NO)
instream-foreign-object (SI) layout-master-set (SI) leader (SI) list-block (SI)
list-item (SI) list-item-body (SI) list-item-label (SI) marker (NO)
multi-case (NO) multi-properties (NO) multi-property-set (NO) multi-switch (NO)
multi-toggle (NO) page-number (SI) page-number-citation (SI) page-sequence (SI)
page-sequence-master (SI) region-after (SI) region-before (SI) region-body (SI)
region-end (NO) region-start (NO) repeatable-page-master-alternatives (SI) repeatable-page-master-reference (SI)
retrieve-marker (NO) root (SI) simple-page-master (SI) single-page-master-reference (SI)
static-content (SI) table (SI) table-and-caption (NO) table-body (SI)
table-caption (NO) table-cell (SI) table-column (SI) table-footer (SI)
table-header (SI) table-row (SI) title (NO) wrapper (NO)

El modelo utilizado por FO está basado en cajas rectangulares llamadas áreas, las cuales pueden contener texto, espacio vacío u otros FO. Cada área tiene borde y separación (padding) por cada uno de sus lados, así como indentaciones (indent) que especifican su separación del área que la contiene. La mayoría de los FO generan un único área, aunque a veces, debido a saltos de página, separación de líneas, etcétera, pueden dar lugar a varias.

Los FO están divididos formalmente en cuatro tipo de áreas rectangulares: contenedores, bloques, líneas e "inclusiones" (inline-areas). Estas cuatro categorías forman una jerarquía muy estricta.

Un contenedor (container area) es la estructura de más alto nivel. Puede ser colocado en coordenas precisas dentro del área que lo contiene. Puede contener otros contenedores, así como secuencias de bloques y de espacios a visualizar. Por ejemplo, una página de un libro es un contenedor que incluye otros cinco contendores: la cabecera, el cuerpo, el pie y los márgenes derecho e izquierdo. Los FO que producen contenedores son: fo:region-body, fo:region-before, fo:region-after, fo:region-start y fo:region-end.

Un bloque (block area) represnta una estructura a nivel de bloque, como un párrafo o un apartado de una lista. Los bloques son colocados secuencialmente dentro del contenedor que los incluye. A su vez, los bloques pueden contener líneas, espacios a visualizar, una imagen y otros bloques (en cuyo caso deben estar separados por una ruptura de línea tanto antes de cada bloque como después de él). Los FO que producen bloques son: fo:block, fo:display-graphic, fo:display-link, fo:display-rule y fo:list-block.

Una línea (line area) hace referencia a cada línea de texto dentro de un bloque. Pueden contener inclusiones así como inclusiones de espacios (inline areas e inline spaces, respectivamente). No existen FO que se correspondan con las líneas, sino que el motor de evaluación del formateo va generándolas conforme divide líneas debido, por ejemplo, al tipo de justificación elegida.

Finalmente, las inclusiones (que es la mejor forma que se me ha ocurrido de traducir el término inline areas :) son partes de una línea, como por ejemplo cada carácter, la referencia a una nota al pie o una expresión matemática. Cada inclusión puede contener otras inclusiones o inclusiones de espacio. Los Fo que generan inclusiones son: fo:character, fo:inline-graphic, fo:inline-link, fo:inline-rule, fo:inline y fo:page-number.

El espacio de nombres FO

Como se ha indicado, los FO no son más que una determinada especificación de la forma de visualizar el contenido de un fichero XML escrita en XSL. Por ello, normalmente se suele preceder a las definiciones de las etiquetas de los FO con el espacio de nombres fo:. Evidentemente, este espacio de nombres debe estar previamente declarado. He aquí cómo se haría:


<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"
	xmlns:fo="http://www.w3.org/XSL/Format/1.0"
	result-ns="fo">

El trozo anterior colocado al principo del fichero XSL que contendrá la renderización de un fichero XML usando FO nos permitirá especificar los nombres de los FO como: fo:block o fo:table, por citar dos ejemplos.

Propiedades

Además de poder definir la estructuración del documento generado a partir de los FO, podemos usar propiedades para especificar más concretamente la renderización que producirá un determinado fichero. Así, por ejemplo, el tamaño de la página, color de texto, etc., pueden ser explicitadas mediante el uso de atributos de los FO.

No es casual que muchas de dichas propiedades atributo se denominen igual que las usadas en las CSS de HTML, de hecho es un reto el hacer que no haya que cambiar los nombres de estas últimas para aprovechar la experiencia adquirida con ellas. Así, por ejemplo, el siguiente código:

<fo:block font-family="Times, Times New Roman">...</fo:block>

es la forma de indicar los tipos de letra que deseamos que tenga el bloque (se comienza por la primera y se continúa hasta encontrar una disponible), siendo font-family una propiedad bien conocida de los usuarios de CSS.

No obstante, FO incluye muchas más propiedades que CSS. Son más de 200 y si he podido transcribirlas es gracias a la página web de Miloslav Nic que se halla en http://zvon.org/xxl/xslfoReference/Output/index.html. Thanks, Miloslav. Indico con la palabra SI las ya implementadas por el proyecto Apache, las demás aún no lo están.

absolute-position active-state alignment-adjust alignment-baseline
auto-restore azimuth background-attachment background-color (SI)
background-image background-position-horizontal background-position-vertical background-repeat
baseline-shift blank-or-not-blank (SI) block-progression-dimension border-after-color (SI)
border-after-precedence border-after-style (SI) border-after-width (SI) border-before-color (SI)
border-before-precedence border-before-style (SI) border-before-width (SI) border-bottom-color (SI)
border-bottom-style (SI) border-bottom-width (SI) border-collapse border-end-color (SI)
border-end-precedence border-end-style (SI) border-end-width (SI) border-left-color (SI)
border-left-style (SI) border-left-width (SI) border-right-color (SI) border-right-style (SI)
border-right-width (SI) border-separation border-start-color (SI) border-start-precedence
border-start-style (SI) border-start-width (SI) border-top-color (SI) border-top-style (SI)
border-top-width (SI) bottom (SI) break-after (SI) break-before (SI)
caption-side case-name case-title character (SI)
clear clip color (SI) color-profile-name
column-count (SI) column-gap (SI) column-number column-width (SI)
content-height content-type content-width country (SI)
cue-after cue-before destination-placement-offset direction
display-align dominant-baseline elevation empty-cells
end-indent (SI) ends-row extent (SI) external-destination (SI)
float flow-name (SI) font-family (SI) font-model
font-selection-strategy font-size (SI) font-size-adjust font-stretch
font-style (SI) font-variant font-weight (SI) force-page-count
format glyph-orientation-horizontal glyph-orientation-vertical grouping-separator
grouping-size height (SI) hyphenate (SI) hyphenation-character (SI)
hyphenation-keep hyphenation-ladder-count hyphenation-push-character-count (SI) hyphenation-remain-character-count (SI)
id (SI) indicate-destination initial-page-number (SI) inline-progression-dimension
internal-destination (SI) keep-together keep-with-next (SI) keep-with-previous
language (SI) last-line-end-indent leader-alignment (SI) leader-length (SI)
leader-pattern (SI) leader-pattern-width (SI) left (SI) letter-spacing
letter-value line-height (SI) line-height-shift-adjustment line-stacking-strategy
linefeed-treatment margin-bottom (SI) margin-left (SI) margin-right (SI)
margin-top (SI) marker-class-name master-name (SI) maximum-repeats (SI)
media-usage number-columns-repeated number-columns-spanned (SI) number-rows-spanned
odd-or-even (SI) orphans overflow padding-after (SI)
padding-before (SI) padding-bottom (SI) padding-end (SI) padding-left (SI)
padding-right (SI) padding-start (SI) padding-top (SI) page-height (SI)
page-position (SI) page-width (SI) pause-after pause-before
pitch pitch-range play-during precedence
provisional-distance-between-starts (SI) provisional-label-separation (SI) ref-id (SI) reference-orientation
region-name (SI) relative-align relative-position rendering-intent
retrieve-boundary retrieve-class-name retrieve-position richness
right (SI) role rule-style (SI) rule-thickness (SI)
scaling scaling-method score-spaces script
show-destination source-document space-after.optimum (SI) space-before.optimum (SI)
space-end space-start space-treatment span (SI)
speak speak-header speak-numeral speak-punctuation
speech-rate src (SI) start-indent (SI) starting-state
starts-row stress suppress-at-line-break switch-to
table-layout table-omit-footer-at-break (SI) table-omit-header-at-break (SI) target-presentation-context
target-processing-context target-stylesheet text-align (SI) text-align-last (SI)
text-altitude text-decoration (SI) text-depth text-indent (SI)
text-shadow text-transform top (SI) treat-as-word-space
unicode-bidi visibility voice-family volume
white-space-collapse widows width (SI) word-spacing
wrap-option (SI) writing-mode z-index

Renderización de Documentos con FO

Lo mismo que podemos pasar de XML a HTML si en el fichero XSL ponemos las etiquetas de HTML como el result-ns y posteriormente lo renderizamos con XP o con Xalan, de igual forma podemos pasr de XML a PDF sin más que poner en el fichero XSL etiquetas de FO, y posteriormente utilizamos el programa FOP para obtener la renderización final en PDF.

FOP está escrito en Java, y puede ser utilizado desde el intérprete de órdenes o bien a través de algún servidor como Cocoon.

Para usarlo desde línea de órdenes hemos de proporcionarle fichero con los FO, que normalmente llevará extensión .fob, así como el nombre del fichero en el que queremos dejar el resultado, que debe llevar extensión .pdf. Estos ficheros podrán visualizarse sin problemas con cualquier lector de este formato, como Acroread, de Adobe, o el xpdf para Linux.

Veamos un primer ejemplo para intentar aclararnos.

Fichero XML


<?xml version="1.0"?> <libro> <titulo> Dos por tres calles </titulo> </libro>
Fichero XSL


<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/XSL/Format/1.0" result-ns="fo" indent-result="yes"> <xsl:template match="libro"> <fo:root xmlns:fo="http://www.w3.org/XSL/Format/1.0"> <fo:layout-master-set> <fo:simple-page-master page-master-name="only"> <fo:region-body/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence> <fo:sequence-specification> <fo:sequence-specifier-single page-master-name="only"/> </fo:sequence-specification> <fo:flow> <fo:block font-size="20pt" font-family="serif"> <xsl:apply-templates select="titulo"/> </fo:block> <fo:block font-size="20pt" font-family="serif"> Otra cosa debajo del titulo </fo:block> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> </xsl:stylesheet>

He destacado en rojo dos cosas porque me interesa que no pasen desapercibidas. En primer lugar que es necesario poner DOS veces xmlns:fo="http://www.w3.org/XSL/Format/1.0", la primera para la hoja de estilos (el fichero XLS) y la segunda para que el fichero .FOB generado la incluya y se le pueda pasar al programa fop para que la procese (como se ve el trozo de código que sigue a este párrafo). La segunda cosa es ver como en efecto, el anterior es código XSL por lo que en el fichero resultante se procesarán las etiquetas del fichero XML tal y como éste XSL lo indique.

Fichero FOB generado, con el cual ejecutaríamos el FOP


<fo:root xmlns:fo="http://www.w3.org/XSL/Format/1.0"> <fo:layout-master-set> <fo:simple-page-master page-master-name="only"> <fo:region-body/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence> <fo:sequence-specification> <fo:sequence-specifier-single page-master-name="only"/> </fo:sequence-specification> <fo:flow> <fo:block font-size="12pt" font-family="serif"> Dos por tres calles </fo:block> <fo:block font-size="12pt" font-family="serif"> Otra cosa debajo del titulo </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
Fichero PDF final: ejemplo.pdf


2. Descripción de Páginas

Páginas Patrón (Master Pages)

El elemento raíz de un FO es fo:root. Este elemento contiene un fo:layout-master-set y cero o más fo:page-sequence. En el elemento raíz se define un espacio de nombres con xmlns:fo="http://www.w3.org/XSL/Formatt/1.0". El elemento raíz no afecta realmente a la renderización final.

El fo:layout-master-set es un contenedor para las diferentes fo:master-page que vayan a usarse en el documento. Cada master page permite definir el patrón para una página, incluyendo los márgenes que tiene, tamaños de cabecera y pie y otras características. Cada página final resultante en la renderización pertencerá a alguno de los patrones definidos por la master page y heradrá ciertas propiedades como márgenes, numeración y aspecto general.

Simple Master Pages

Se representan con fo:simple-page-master, las cuales pueden estar incluidas en un fo:layout-master-ser, como ya sabemos. Definen el aspecto de cada página patrón especificando los tamaños de sus regiones anterior, posterior, cuerpo, inicio y fin; respectivamente serían: fo:region-before, fo:region-after, fo:region-body, fo:region-start, fo:region-end, las cuales a su vez pueden ser rellenadas de contenido usando fo:flow o fo:static-content. Gráficamente se corresponden por las mostradas en la siguiente figura.

Tres son los atributos principales de la fo:simple-page-master. A saber: page-master-name, page-height y page-width (nótese la ausencia de fo: dado que NO son FO sino atributos de FO). Estas dos últimas se pueden resumir en una sola denominada size. Si no se proporcionan valores se toma uno por defecto (normalmente 8" por 11").

El siguiente trozo de código define dos páginas patrones, una para las pares y otra para las impares.


<fo:layout-master-set>
  <fo:simple-page-master page-master-name="impar"
      height="29cm" width="21cm" margin-top="0.5cm" margin-bottom="0.5cm"
	margin-left="1.0cm" margin-right="0.5cm">
     <fo:region body/>
  </fo:simple-page-master>
  <fo:simple-page-master page-master-name="par"
      height="29cm" width="21cm" margin-top="0.5cm" margin-bottom="0.5cm"
	margin-left="0.5cm" margin-right="1.0cm">
     <fo:region body/>
  </fo:simple-page-master>
</fo:master-page-set>

Las cinco regiones existentes dentro de cada página patrón comparten atributos básicos que sirven para determinar qué hacer con el contenido que se escapa por los bordes (clip, overflow), cómo se divide en columnas, atributos sobre el fondo o base (background) de la región, sobre los bordes de la misma, la separación con su contenido (padding), los márgenes que la separan de su contenedor y el sentido de la escritura.

Además de esas, todas menos fo:region-body tienen una propiedad llamada extent que indica el tamaño de cada región. Para fo:region-before y fo:region-after dicha propiedad indicará la altura, mientras que para fo:region-start y fo:region-end indicará la anchura.

Secuencias de páginas (Page Sequences)

Cada documento generado con FO debe tener una o más fo:page-sequence, cada una de las cuales a su vez tiene: una fo:sequence-specification (indicando el orden en que las páginas patrón son usadas), cero o más fo:static-content con texto a incluir en todas las páginas, y un fo:flow con datos que se incluirán en cada página según vaya cayendo.

Sequence specification

Como ya se ha dicho, lista el orden en que serán aplicadas las distintas páginas patrón. Para ello, incluye otros FO que pueden ser uno o varios de los siguientes: fo:sequence-specifier-single, fo:sequence-specifier-alternating y fo:sequence-specifier-repeating. Cada uno de estos FO tiene atributos que permiten definir el orden de las páginas patrón a usar. Veamos algunos ejemplos:

Una misma página patrón para todo el contenido


<fo:sequence-specification> <fo:sequence-specifier-single page-master-name="par"/> <fo:sequence-specification>
Una misma página patrón para todo el contenido suponiendo que va a acupar tres páginas 


<fo:sequence-specification> <fo:sequence-specifier-single page-master-name="impar"/> <fo:sequence-specifier-single page-master-name="impar"/> <fo:sequence-specifier-single page-master-name="impar"/> <fo:sequence-specification>
Distintas páginas patrón para todo el contenido suponiendo que va a ocupar dos páginas 


<fo:sequence-specification> <fo:sequence-specifier-single page-master-name="impar"/> <fo:sequence-specifier-single page-master-name="par"/> <fo:sequence-specification>

Como de antemano no sabemos cuántas páginas va a ocupar el contenido, debemos echar mano de fo:sequence-specifier-repeating y fo:sequence-specifier-alternating. El primero de estos FO permite especificar dos páginas patrones: una para la primera página y otra para todas las demás. Mientras que el segundo permite especificar hasta 6 páginas patrón: una para la primera págna, otra para las páginas pares con contenido, otra para las impares con contenido, otra para páginas pares en blanco, para la última hoja par y la última hoja impar. Veamos unos un ejemplos.

Primera página de tipo portada, las siguientes de tipo pagina


<fo:sequence-specification> <fo:sequence-specifier-repeating page-master-first="portada" page-master-repeating="pagina" /> </fo:sequence-specification>
Todas las páginas del tipo pagina (en número indefinido).


<fo:sequence-specification> <fo:sequence-specifier-repeating page-master-first="pagina" page-master-repeating="pagina" /> </fo:sequence-specification>
Ejemplo completo para describir un capítulo:


<fo:sequence-specification> <fo:sequence-specifier-alternating page-master-first="cap_portada" page-master-even="cap_pares" page-master-blank-even="cap_blanca" page-master-odd="cap_impares" page-master-last-even="cap_ultima_par" page-master-last-odd="cap_ultima_impar" page-master-repeating="cap_ultima_par" /> </fo:sequence-specification>

Contenido dinámico (flows)

El objeto fo:flow ubica el contenido que será colocado en las páginas. Este contenido está compuesto de una secuencia de fo:block, fo:display-graphic, fo:display-link, fo:display-rule y otros elementos colocados al mismo nivel de bloque.

El objeto fo:flow tiene un atributo llamado flow-name cuyos valores pueden ser: xsl-body, xsl-after, xsl-before, xsl-start y xsl-end, que indican en qué parte de la página se coloca el contenido.

Nota al pie de página.


<fo:flow flow-name="region-after"> <fo:block>Creado por Pepe Illo</fo:block> </fo:flow>

Contenido estático (Static Content)

Los fo:static-content sirven para especificar contenido que aparecerá en todas las páginas, pudiendo contener internamente los mismos contenidos que un fo:flow (aunque normalmente en número más reducido dado que no se pueden extender a más de una página). Hay que tener en cuenta que, cuando se usan los contenidos estáticos, deben aparecer antes de los elementos fo:flow al definir la secuencia de elementos de la página.

Pie de página.


<fo:static-content flow-name="region-after"> <fo:block>(C) GeNeura 2001</fo:block> </fo:static-content>

Numeración de páginas

Además de una secuencia de páginas patrón a usar, contenidos estáticos y contenidos dinámicos, un fo:page-sequence tienen seis atributos opcionales relativos a la numeración, que son initial-page-number, format, letter-value, digit-group-sep, n-digits-per-group y sequence-src.

Con esos atributos solo definimos el formato de la numeración, pero para poner el número de página como tal hemos de incluir el fo:page-number dentro de un fo:block, fo:inline o algo similar para decir dónde va y qué tipo de letra, color, etc. tiene.

Número de página en la cabecera, contando a partir de 5 en números romanos, centrado y a tamaño 12


<fo:page-sequence initial-page-number="5" format="i"> <fo:static-content flow-name="xsl-before"> <fo:block text-align-last="centered" font-size="12pt"> <fo:page-number/> </fo:block> </fo:static-content> </fo:page-sequence>

3. Contenido

Introducción

El contenido que normalmente vamos a incluir es de tipo texto, aunque también se pueden incluir imágenes, casi de la misma forma que en HTML se hace con IMG.

El contenido se organiza en elementos de tipo bloque, inclusiones, tablas y objetos "fuera de línea".

FO a nivel de Bloques

Un FO a nivel de bloque se entiende como un área rectangular separada por un alínea de ruptura y, posiblemente, espacio añadido antes y después de lo que contenga. Los bloques pueden contener otros bloques. Los FO a nivel de bloque son: fo:block, fo:display-graphic, fo:display-rule, fo:display-include-container, fo:display-sequence, fo:list-block y fo:list-item

Block

Los fo:block pueden estar contenidos en fo:flow, fo:static-content u otros fo:block. Ellos pueden contener a otros fo:block, así como fo:display-graphic y fo:display-rule (ambos a nivel de bloque), y también fo:inline y fo:page-number (a nivel de inclusiones). Por supuesto, también pueden tener texto plano.

Ejemplo de bloque


<fo:block> <fo:inline font-style="italic"> Esto está en letra italica </fo:inline> Página: <fo:page-number/> <fo:inline> Esto no lo está !! </fo:inline> </fo:block>

display-graphic

Sirve para insertar un gráfico a nivel de bloque (a diferencia de fo:inline-graphic que lo insertaría a nivel de inclusión - ver más abajo). Entre sus propiedades destacan href (con la dirección del gráfico), min-height, min-width, max-height, max-width (con las alturas y anchuras mínimas y máximas respectivamente), scale (que puede tomar los valores max - para expandir al máximo la imagen -, max-uniform - para expandir la imagen hasta máxima anchura o máxima altura, lo que llegue antes, un número real - por el que multiplicar ambas anchura y altura -, o dos números reales - el primero para la anchura y el segundo para la altura -).

display-rule

Una rule es una línea, que podemos colocar tanto en horizontal como en vertical. Si en vez de a nivel de bloque la deseamos a nivel de inclusión usaremos fo:inline-rule.

Entre sus propiedades destacamos length, rule-orientation (con los posibles valores horizontal, escapement, line-progression o vertical), rule-thickness, vertical-align (baseline, bottom, middle, sub, super, text-bottom, text-top, top o una longitud o porcentaje de longitud) y finalmente color.

list-block y list-item

Un fo:list-block es el contenedor de una serie de items que se enseñarán en forma de lista. No existen inclusiones de lista. Un fo:list-block puede contener o bien una serie de fo:list-item, o bien pares de fo:list-item-label fo:list-item-body, pero no ambas cosas a la vez.

Primer ejemplo de lista.


<fo:list-block> <fo:list-item> <fo:list-item-label>*</fo:list-item-label> <fo:list-item-body>Primer elemento de la lista</fo:list-item-label> </fo:list-item> <fo:list-item> <fo:list-item-label>*</fo:list-item-label> <fo:list-item-body>Segundo elemento de la lista</fo:list-item-label> </fo:list-item> </fo:list-block>
Segundo ejemplo de lista.


<fo:list-block> <fo:list-item-label>*</fo:list-item-label> <fo:list-item-body>Primer elemento de la lista</fo:list-item-label> <fo:list-item-label>*</fo:list-item-label> <fo:list-item-body>Segundo elemento de la lista</fo:list-item-label> </fo:list-block>

Los fo:list-block tienen tres propiedades de especial relevancia: provisional-label-separation (se le dan tres valores de distancia separados por punto y coma - ejemplo: 2cm;0.5cm;1cm - indicando valor máximo, mínimo y óptimo, respectivamente), provisional-distance-between-starts (distancia desde el comienzo del eje de la etiqueta y el comienzo del eje del cupero del item) y space-between-list-rows (distancia entre los sucesivos items, especificado también como una tripleta máximo;mínimo;óptimo).

FO de inclusiones

Una inclusión es un área rectangular que puede contener texto u otras inclusiones. Se suelen mostrar dentro de líneas y de izquierda a derecha. Lo FO que se corresponden con inclusiones son: fo:bidi-override, fo:character, fo:first-line-marker, fo:inline-graphic, fo:inline-include-container, fo:inline-rule, fo:inline-sequence, fo:list-item-body, fo:list-item-label, fo:page-number y fo:page-number-citation.

Algunas se corresponden con la versión inclusión de sus compañeras a nivel de bloque, tales como fo:inline-rule o fo:inline-graphic. Otras ya las hemos utilizado previamente, como fo:list-item-body, fo:list-item-label y fo:page-number .

FO para enlaces

Un enlace tiene poco sentido en un documento impreso, pero tiene mucho en la versión electrónica de dicho documento. Para introducir enlaces, FO incluye el elemento fo:simple-link el cual puede actuar como un elemento de bloque o de inclusión según su contenido.

Para controlar su comportamiento se le han asignado seis atributos: external-destination, internal-destination, indicate-destination, show-destination, space-above-destination-block y space-above-destination-start.

Un enlace a un documento remoto se especifica asignándole su URI a external-destination. Un enlace a un recurso del propio decumento se indica asinándole el valor del identificador de dicho recurso a la propiedad internal-destination. Un enlace no puede tener estos dos atributos a la vez.

fo:show-destination acepta los valores replace (por defecto) o new, que permite cargar en la misma ventana o en otra distinta (respectiamente) el documento destino indicado por el enlace.

Por último, fo:space-above-destination-start y fo:space-above-destination-block permiten indicar si cuando se cargue el documento destino se va a poner el punto exacto indicado por el enlace en la parte superior del navegador, o por el contrario se va a desplazar hacia abajo (no dejando espacio vacío, sino con el contenido que lo preceda).

4. Referencias

Libros

Para realizar este tutorial me he basado básicamente en el capítulo 15 del siguiente libro:

- Elliotte Rusty Harold. XML Bible. Ed. Hungry Minds, Inc, 1999. (ISBN: 0764532367) (En Inglés)

* Aunque en algunos lugares he visto que existe una versión actualizada en esta dirección: ¿¿??, lo cierto es que no he conseguido conectar con dicho sitio nunca.

Direcciones WEB

Las siguientes direcciones también pueden ser de gran ayuda:

* Utilidades para FO en el sitio de XMLSoftware: http://www.xmlsoftware.com/xpath/

* El Apache Project: http://xml.apache.org/fop

* Una magnífica guía de referencia: http://zvon.org/xxl/xslfoReference/Output/index.html

* Del mismo sitio anterio, pero comprimida en formato zip

* El programa FOP como parte del Apache Project. Sitio original: http://xml.apache.org/. Copia local: software/fop-0_16_0.zip (incluye documentación: software/fop-0_16_0_docs.zip)