=head1	NAME

ODF::lpOD::Style - Styles management

=head1  DESCRIPTION

A style controls the formatting and/or layout properties of a family of
content objects. It's identified by its own name and its family.
In the lpOD API, the family has a larger acception than in the OpenDocument
specification. In the underlying XML, the family is indicated sometimes
by the value of an explicit C<style:family> attribute, and sometimes by the
XML tag of the style element itself.

In order to hide the complexity of the ODF data structure, the level 1 API
allows the user to handle any style as a high level I<odf_style> object.

=head1 Common style features

Any style is created through a common C<odf_create_style()> function with the
family as its mandatory first argument. A name, that is the identifier of
the style in the given family, is generally required. So, a typical style
creation instruction looks like:

   $s = odf_create_style('text', name => 'MyTextStyleName');

The example above creates a named text style without any property. The
properties are optionally passed as named parameters.

Additional named parameters can be required according to the family. An optional
C<parent> argument, whose value is the name of another common style of
the same family (existing or to be created), can be provided, knowing that a
style inherits (but can override) all the properties of its parent. A
C<display name> additional parameter may be provided; if set, this parameter
designates a visible name that may differ from the internal name. It's
possible to copy (instead of inherit) all the properties of an existing style
of the same family, through a C<clone> option, knowing that C<clone> and
C<parent> are mutually exclusive options. The code example below produces two
text styles whose properties are the same as "MyTextStyleName", but the first
one will be affected by later changes of the base style while the second one
is independant:

   odf_create_style('text', name => 'NewStyle1', parent => 'MyTextStyleName');
   $proto = doc->get_style('text', 'MyTextStyleName');
   odf_create_style('text', name => 'NewStyle2', clone => $proto);

An effective style name, unique for the family, is required as soon as the
style is attached to a document, unless it's inserted as a I<default style>.
This name may be set or changed with C<set_name()> after the style creation.
When a style is used as a default style, its name and display name are
meaningless and ignored. The family and the name constitute the absolute
identifier of a style in a document.

The C<odf_create_style()> function creates a free element, not included in a
document. This element (or a clone of it) is available to be attached later
to a document through a generic, document-based C<insert_style()> method.

The C<insert_style()> method requires a style object as its only one mandatory
argument. An optional boolean parameter whose name is C<default> is allowed;
if provided and set to C<TRUE>, this parameter means that the style is inserted
as a I<default style>. A default style is a style that automatically apply to
elements whose style is not explicitly specified. A document can contain
at most one default style for a style family, so any attachment of a default
style replaces any existing default style of the same family.

All styles can't be used as default styles. Default styles are allowed
for the following families: C<paragraph>, C<text>, C<section>, C<table>,
C<table column>, C<table row>, C<table cell>, C<table page>, C<chart>,
C<drawing page>, C<graphic>, C<presentation>, C<control> and C<ruby>.

Some styles may have a I<class> property, that is an informative attribute, and
that should not be confused with the I<family>. A family is an application-
defined property, used in order to identify a set of styles belonging to various
families, for retrieval needs.

An existing style may be retrieved in a document using the C<get_style()>
document-based method. This method requires a family as its first argument and
allows a style name as a second, optional argument. If the name is missing,
this method tries to retrieve the default style for the given family, if any.

The following example extracts a paragraph style, so-called "MyParagraph", from
a document and attaches a clone of this style as a default style of another
document; the old default paragraph style of the target document (if any) is
automatically replaced::

   $ps = $doc1->get_style('paragraph', 'MyParagraphStyle')->clone();
   $doc2->insert_style($ps, default => TRUE);

While a style is identified by name and family, it owns one or more sets of
properties. A style property is a particular layout or formatting behaviour.
The API provides a generic C<set_properties()> method which allows the user to
set these properties, while C<get_properties()> returns the existing properties
as an associative array.

However, some styles have more than one property set.

As an example, a paragraph style owns so-called "paragraph properties"
and/or "text properties" (see below). In such a situation, an additional
C<area> parameter, whose value identifies the particular property set, with
C<set_properties()>. Of course, the same C<area> parameter applies to
C<get_properties()>.

Some styles allow the applications to specify a I<background>. Such a background
is sometimes characterized by the RGB, 3-bytes hexadecimal code of an arbitrary
color, with a leading "#". However some styles allow the use of backround image
instead of or in combination with a color. In order to deal with these
possibilities, a C<set_background()> is provided; this method (which works
with some style objects only) is used with a C<color> and/or a C<url> named
parameters. The C<color> value range is #000000-#ffffff, while C<url> should
be set to the URL of the graphic resource. If C<url> is set, some additional
optional parameters may be provided, in order to control the way the image is
displayed in the background, namely:

=over

=item

C<position>: a string that specifies the horizontal and vertical positions
of the image, through one or two space-separated words (in any order) among
C<center>, C<left>, C<right>, C<top>, C<bottom> (default: C<center>);

=item

C<repeat>: specifies whether a background image is repeated or stretched,
whose possible values are ``no-repeat`` meaning that the image should be
displayed once, ``repeat`` to repeat the image in order to fill the whole
background, and ``stretch`` to extend the image in order to fill the
whole background;

=item

C<opacity>: the percentage of opacity;

=item

C<filter>: an application-specific filter to that is used to load and process
the graphic file, according to the image format.

=back

To remove the background color or image (i.e. to set the background to the
default, that is transparent), the user just have to call C<set_background()>
with C<color> and C<url> set to C<undef>.

A style that apply in some way to a rectangular area (ex: shape, frame,
paragraph) other than a page may have visible borders and a shadow. Borders are
specified using C<border xxx> attributes where C<xxx> is either C<left>,
C<right>, C<top> or C<bottom>; if all the borders are the same, a single
C<border> property is convenient. The value of a border property is a 3-part
string that describes the thickness, the line style and the line color
(according to the XSL/FO grammar), like C<"0.1cm solid #000000"> for a one
millimeter solid black line. The shadow is specified through a C<shadow>
property whose value is a 3-part string describing the color and the size, like
C<"#808080 0.18cm 0.18cm">.

A style can be inserted as either I<common> (or named and visible for the
user of a typical office application) or I<automatic>, according to a boolean
C<automatic> option, whose default value is C<FALSE>. A common style may have
a secondary unique name which is its C<display name>, which can be set through
an additional option. With the exception of this optional property, and a
few other ones, there is no difference between automatic and common styles.

Defaults styles and common styles are automatically inserted in the C<STYLES>
document part. But automatic styles may be inserted, at the user's choice, in
C<CONTENT> or C<STYLES>. The default is C<CONTENT> but C<STYLES> may be
specified through a C<part> optional parameter of C<insert_style()>. The user
must check that any automatic style is inserted in the same document part as
the element that uses it (so, an automatic style must be inserted in C<STYLES>
if it's used by another style defined in this part).

Of course, a style is really in use when one or more content objects
explicitly reference it through its style property.

The API allows the user to retrieve and select an existing style by name and
family. The display name, if set, may be used as a replacement of the name
for retrieval.

Once selected, a style could be removed from the document through a standard
level 0 element deletion method.

=head1  Text styles

A text style can be defined either to control the layout of a text container,
i.e. a paragraph, or to control a text range inside a paragraph. So the API
allows the user to handle two families of text styles, so called I<text>
and I<paragraph>. For any style in the text or paragraph families, the I<text>
class is recommended.

=head2  Text family

A text style (i.e. a style whose family is C<text>, whatever its optional
class) is a style which directly applies to characters (whatever the layout
of the containing paragraph). So, it can bear any property directly
related to the font and its representation. The most used properties are
the font name, the font size, the font style (ex: normal, oblique, etc),
the text color, the text background color (which may differ from the
common background color of the paragraph).

A text style may apply to any text span in any text paragraph. However some ODF
editing or viewing applications don't fully support them in some situations. For
example, OpenOffice.org doesn't currently allow the use of I<common> text styles
with spreadsheets, while it allows I<common> and I<automatic> text styles in text
documents.

A text style can apply to one or more text spans; see the "Text spans"
section. It can be used as the default text style of a document. In addition,
an existing text style may be reused to set the text properties of a paragraph
style (see below).

The example hereafter creates a text style, so called "My Colored Text",
using Times New Roman, 14-sized navy blue bold italic characters with
a yellow background::

   $s = odf_create_style('text',
                        name            => 'MyColoredText',
                        'display name'  => 'My Colored Text',
                        font            => 'Times New Roman',
                        size            => '14pt',
                        weight          => 'bold',
                        style           => 'italic',
                        color           => '#000080'
                        );
   $s->set_background(color => '#ffff00')

This new style could be inserted using C<insert_style()> then retrieved and
changed later using C<get_style()> then the C<set_properties()> method of the
style object. For example, the following code modifies an existing text style
definition so the font size is increased to 16pt and the color turns green:

   $s = $document->get_style('text', 'MyColoredText');
   $s->set_properties(size => '16pt', color => '#00ff00');

The C<set_properties()> method may be used in order to delete a property,
without replacement; to do so, the target property must be set to C<undef>.

Note that C<set_properties()> can't change any identifying attribute such
as name, family or display name.

The lpOD level 1 API allows the applications to set any property without
ODF compliance checking. The compliant property set for text styles is
described in the section §15.4 of the OASIS ODF specification. Beware,
some of them are not supported by any ODF text processor or viewer.

The API allows the user to set any attribute using its official name
according to the ODF specification (§15.4). For example, the properties
which control the character name and size are respectively
C<fo:font-name> and C<fo:font-size>. However, the API allows the use of
mnemonic shortcuts for a few, frequently required properties, namely:

=over

=item

C<font>: font name;

=item

C<size>: font size (absolute with unit or percentage with '%');

=item

C<weight>: font weight, which may be C<normal>, C<bold>, or one of the
official nine numeric values from C<100> to C<900> (§15.4.32);

=item

C<style>: to specify whether to use normal or italic font face; the
legal values are C<normal>, C<italic> and C<oblique>;

=item

C<color>: the color of the characters (i.e. foreground color), provided
as a RGB, 6-digit hexadecimal string with a leading '#';

=item

C<underline>: to specify if and how text is underlined; possible values
are C<solid> (for a continuous line), C<dotted>, C<dash>, C<long dash>,
C<dot dash>, C<dot dot dash>, C<wave>, and C<none>;

=item

C<display>: to specify if the text should by displayed or hidden;
possible values are C<true> (meaning visible) C<none> (meaning hidden)
or C<condition> (meaning that the text is to be visible or hidden
according to a condition defined elsewhere).

=back

A text style may have a background color, but not a background image.

=head2  Paragraph family

A paragraph style apply to paragraphs at large, i.e. to ODF paragraphs and
headings, which are the common text containers. It controls the layout of both
the text content and the container, so its definition is made of two distinct
parts, the I<text> part and the I<paragraph> part.

The text part of a paragraph style definition may have exactly the same
properties as a regular text style. The rules are defined by the §15.4 of the
OASIS 1.1 ODF specification, and the API provides the same property shortcuts as
for a text style creation. Practically, this text part defines the default text
style that apply to the text content of the paragraph; any property in this part
may be overriden as soon as one or more text spans with explicit styles are
defined inside the paragraphs.

The creation of a full-featured paragraph style takes two steps. The first one
is a regular C<odf_create_style()> instruction, with C<paragraph> as the value
of the family mandatory argument, a name parameter (unless the user just wants
to create a default style) and any number of named paragraph properties. The
second (optional) step consists of appending a I<text> part to the new paragraph
style; it can be accomplished, at the user's choice, either by specifying a
previously defined text style element, or by explicitly defining new text
properties, through the C<set_properties()> method with the C<area> option set
to C<text>. In the second case, the prototype text style is provided through
the C<clone> parameter.

Assuming that a "MyColoredText" text style has been defined according to the
text style creation example above, the following sequence creates a new
paragraph style whose text part is a clone of "MyColoredText", and whose
paragraph part features are the text justification, a first line 5mm indent,
a black, continuous, half-millimiter border line with a bottom-right, one
millimeter grey shadow, with other possible properties inherited from a
"Standard" style:

   $ps = odf_create_style(
                        'paragraph',
                        name            => 'BorderedShadowed',
                        'display name'  => 'Strange Boxed Paragraph',
                        parent          => 'Standard',
                        align           => 'justify',
                        indent          => '5mm',
                        border          => '0.5mm solid #000000',
                        shadow          => '#808080 1mm 1mm'
                        );
   $ts = $document->get_style('text', 'MyColoredText');
   $ps->set_properties(area => 'text', clone => $ts);

Note that "MyColoredText" is reused by copy, not by reference; so the new
paragraph style will not be affected if "MyColoredText" is changed or deleted
later.

The value of the C<clone> parameter, if any, may be a I<paragraph> style
element instead of a I<text> style element, provided that the given paragraph
style contains a I<text> part; so the text part of the given paragraph style (and
this part only) is used as the prototype.

The API allows the user to set any attribute using its official name according
to the ODF specification related to the paragraph formatting properties (§15.5).
However, the API allows the use of mnemonic shortcuts for a few, frequently
required properties, namely:

=over

=item

C<align>: text alignment, whose legal values are C<start>, C<end>, C<left>,
C<right>, C<center>, or C<justify>;

=item

C<align-last>: to specify how to align the last line of a justified paragraph,
legal values are C<start>, C<end>, C<center>;

=item

C<indent>: to specify the size of the first line indent, if any;

=item

C<widows>: to specify the minimum number of lines allowed at the top of a page
to avoid paragraph widows;

=item

C<orphans>: to specify the minimum number of lines required at the bottom of a
page to avoid paragraph orphans;

=item

C<together>: to control whether the lines of a paragraph should be kept together
on the same page or column, possible values being C<always> or C<auto>;

=item

C<margin>: to control all the margins of the paragraph;

=item

C<margin xxx> (where C<xxx> is C<left>, C<right>, C<top> or C<bottom>): to
control the margins of the paragraph separately;

=item

C<border>: a 3-part string to specify the thickness, the line style and the line
color (according to the XSL/FO grammar);

=item

C<border xxx> (where C<xxx> is C<left>, C<right>, C<top> or C<bottom>): the same
as C<border> but to specify a particular border for one side;

=item

C<shadow>: a 3-part string to specify the color and the size of the shadow;

=item

C<padding>: the space around the paragraph;

=item

C<padding xxx> (where C<xxx> is C<left>, C<right>, C<top> or C<bottom>): to
specify the space around the paragraph side by side;

=item

C<keep with next>: to specify whether or not to keep the paragraph and the next
paragraph together on a page or in a column, possible values are C<always> or
C<auto>;

=item

C<break xxx> (where C<xxx> is C<before> or C<after>): to specify if a page or
column break must be inserted before or after any paragraph using the style,
legal values are C<page>, C<column>, C<auto>.

=back

A pararaph style may have a background color or image.

=head2  List family

A list style is a set of styles that control the formatting properties of
the list items at every hierachical level. As a consequence, a list style
is a named container including a particular style definition for each level;
in other words a list style is a set of list level styles.

The API allows the user to create a list style (if not previously existing
in the document), and to create, retrieve and update it for any level.

A new list style, available for later insertion in a document, is created
through the C<odf_create_style()> function. The only mandatory argument is
the style family, which is C<list>. However, a name is generally required as
the second argument, knowing that a style list can't presently be used as a
default style; an error is raised at any attempt to attach a nameless list
style using C<insert_style()>. An optional display name argument is allowed
(if the style list is about to be used as a common style); if  provided, the
display name should be unique as well.

An existing list style object provides a C<set_level_style()> method,
allowing the applications to set or change the list style properties for a
given level. This method requires the level number as its first argument,
then a C<type> named parameter may be provided. The level is a positive (non
zero) integer value that identifies the hierarchical position. The type
specifies what kind of item mark is should be selected for the level; the
possible types are C<number>, C<bullet> or C<image>. The default is C<number>.

If the C<bullet> type is selected, the affected items will be displayed after
a special character (the "bullet"), which must be provided as a C<character>
named argument, whose value is an UTF-8 character.

If the C<image> type is selected, the URL of an image resource must be
provided; the affected items will be displayed after a graphical mark whose
content is an external image.

A C<number> list level type means that any affected list item will be marked
with a leading computed number such as "1", "i", "(a)", or any auto-
incremented value, whose formatting will be controlled according to other
list level style properties (or to the default behaviour of the viewer for
ordered lists). With the C<number> type, its possible to provide C<prefix>
and/or C<suffix> options, which provide strings to be displayed before and
after the number. Other optional parameters are:

=over

=item

C<style>: the text style to use to format the number;

=item

C<display levels>: the number of levels whose numbers are displayed at the
current level (ex: if display-levels is 3, so the displayed number could
be something like "1.1.1");

=item

C<format>: the number format (typically "1" for a simple number display),
knowing that if this parameter is null the number is not visible;

=item

C<start value>: the first number of a list item of the current level.

=back

The following example shows the way to create a new list style then
to set some properties for levels 1 to 3, each one with a different type:

   $ls = odf_create_style('list', name => 'ListStyle1');
   $ls->set_level_style(1, type => 'number', prefix => ' ', suffix => '. ');
   $ls->set_level_style(2, type => 'bullet', character => '-');
   $ls->set_level_style(3, type => 'image', url => 'bullet.jpg');

The C<set_level_style()> method returns an ODF element, representing the list
level style definition, and which could be processed later through any element-
or style-oriented function.

An individual list level style may be reloaded through C<get_level_style()>,
with the level number as its only one argument; it returns a regular ODF element
(or C<undef> if the given level is not defined for the calling list style).

It's possible to reuse an existing list level style definition at another level
in the same list style, or at any level in another list style, or in another
document. To do so, the existing level style (previously extracted by any mean,
including the C<get_level_style()> method) must be provided as a special
C<clone> parameter to C<set_level_style()>. The following example reuses the
level 3 style of "ListStyle1" to define or change the level 5 style of
"ListStyle2":

   $ls1 = $document->get_style('list', 'ListStyle1');
   $source = $ls1->get_level_style(3);
   $ls2 = $document->get_style('list', 'ListStyle2');
   $ls2->set_level_style(5, clone => $source);

The object returned by C<set_level_style()> or C<get_level_style()> is
similar to an ODF style object, without the name and the family. So the generic
C<set_properties()> method may be used later in order to set any particular
property for any list level style. Possible properties are described in section
§14.10 of the ODF specification.

Every list level style definition in a list style is optional; so it's not
necessary to define styles for levels that will not be used in the target
document. The C<set_level_style()> method may be used with an already defined
level; in such a situation, the old level style is replaced by the new one. So
it's easy to clone an existing list style then modify it for one or more levels.

=head2  Outline style

According to the ODF specification, "the outline style is a list style that
is applied to all headings within a text document where the heading's paragraph
style does not define a list style to use itself".

Practically, the outline style is a particular list style which controls the
layout of a particular hierarchical list. In other words, it's a list
of default styles for headings according to their respective hierarchical
levels.

The outline style, like any list style, should define a style for each level
in use in the document.

The API allows the user to initialize the outline style (if not previously
existing in the document), and to create, retrieve and update it for any level.

The C<get_style()> method allows the user to get access to the outline
style structure; to do so, C<outline> must be provided in place of the family
argument. The returned object is a nameless list style; it may be
cloned in order to be reused as the outline style for another document, or as
an ordinary list style (provided that it's later named). If the outline style
is not initialized yet, C<get_style()> returns a null value for the C<outline>
family.

If needed, the outline style can be created through C<odf_create_style()>
with C<outline> as the style family and without name, then attached using
C<insert_style()>. The style for each individual level may be set, retrieved
and changed at any time using the object-based C<set_level_style()> and
C<get_level_style()> methods.

Unlike with regular list styles, the C<type> option of C<set_level_style()>
is ignored with the outline style; the type is automatically C<number> (i.e.
the outline style is always a numbered list style).

The API allows the user to set style attributes for any level, knowing that a
level is identified by a positive integer starting from 1. With the current
version of the lpOD level 1 API, a few outline level style attributes are
supported, namely:

=over

=item

C<prefix>: a string that should be displayed before the heading number;

=item

C<suffix>: a string that should be displayed before the heading number;

=item

C<format>: the number display format (ex: 1, "A");

=item

C<display levels>: the number of levels whose numbers are displayed at
the current level;

=item

C<start value>: the first number of a heading at this level;

=item

C<style>: the name of the style to use to format the number (that is a
regular text style).

=back

As an example, the following code retrieves the default style for the level 4
headings:

   $os = $document->get_style('outline');
   $head4 = $os->get_level_style(4);

The next example sets some properties for any level 1 heading, namely a
numbering starting from 5 and the use of capital letters between parentheses
as numbers:

   $os = $document->get_style('outline');
   $os->set_level_style(
        1,
        start_value => 5, prefix => '(', suffix => ')', format => 'A'
        ):

According to the example above, the default numbering scheme for level 1
headings will be "(E)", "(F)", "(G)", and so on.

Attributes and properties which are not explicitly supported through predefined
parameter names in the present version of the API could always be set hrough
the element-oriented methods of the level 0 API, knowing that
C<get_level_style()> returns a regular element.
