NAME
    RTF::Group - Base class for manipulating Rich Text Format (RTF) groups

DESCRIPTION
    This is a base class for manipulating RTF groups. Groups are stored
    internally as lists. Lists may contain (sub)groups or atoms (raw text or
    control words).

    Unlike the behavior of groups in the original `RTF::Document module'
    (versions 0.63 and earlier), references to arrays (lists) are *not*
    treated as subgroups, but are dereferenced when expanded (as lists or
    strings).

    This allows more flexibility for changing control codes within a group,
    without having to know their exact location, or to use kluges like
    *splice* on the arrays.

    I am in the process of writing a `RTF::Generator' module which will
    supercede `RTF::Document'.

METHODS
  new

        $group = new RTF::Group LIST, PROPERTIES;

    Creates a new group. If LIST is specified, it is appended to the group.
    PROPERTIES are optional, and are used to set properties for the object.

    By default, the `subgroup' property is set. This means that if the group
    is appended to another group, it will be emitted (using the `_list' and
    `as_string' methods) as a group within a group:

        $g1 = new RTF::Group(g1);
        $g2 = new RTF::Group(g2);
        $g1->append($g2);
        print $g1->as_string;       # emits '{g1{g2}}'

    If we disable the `subgroup' property, we get the following:

        $g1 = new RTF::Group(g1);
        $g2 = new RTF::Group(g2, {subgroup=>0});
        $g1->append($g2);
        print $g1->as_string;       # emits '{g1 g2}'

    The `escape' property enables automatic escaping of unescaped curly
    brackets when a group is emitted as a string. (This property is also
    enabled by default.)

    The `wrap' property is not used in this version.

    Each property is also a method for getting or setting it's value. For
    example,

        unless ($g2->subgroup)
        {
            $g2->subgroup(1);
        }

    See the `append' method for more details on how groups are handled.

  append

        $group->append LIST;

    Appends LIST to the group. LIST may be plain text, controls, other
    groups, or references to a SCALAR or another LIST.

    If LIST contains another RTF::Group, it will be embedded as a subgroup
    (how this is handled is explained in the the documentation for the `new'
    method).

    If LIST contains a reference to a SCALAR, the value it points to will be
    emitted when the `_list()' or `_string' methods are called.

    If LIST contains a reference to CODE, the value that code returns will
    be emitted as if it were returned by `_list()'. For insance,

        sub generator
        {
            my $arg = shift;
            return uc($arg);
        }

        $g1 = new RTF::Group(g1);
        $g1->append( \&generator, 'g2' );

        print $g1->as_string();            # emits '{g1 G2}'

    Note that `\&generator' must have one and only one argument, which is
    following item on the list. The argument is *not* processed by
    `RTF::Group'.

  as_string

        print $group->as_string();

    Returns the group as a string that would appear in an RTF document. (The
    deprecated `string' method is an alias for `as_string'.)

  is_empty

        if ($group->is_empty) { ... }

    Returns true if the group is empty, false if it contains something.
    Zero-length strings are considered nothing.

  _list

        @RTF = $group->_list LIST;

    "Parses" LIST by dereferencing scalars, arrays or subgroups. If LIST is
    not specified, parses group. (Although this may useful for parsers, it
    is intended for internal use *(read: private method)*.)

  _list_as_string

        $output = $group->_list_as_string( LIST )

    Converts the output of the `_list()' method into a string. This is a
    private method and may go away in future versions: use the `as_string'
    method instead.

  _escape

        $atom = RTF::Group::_escape( SCALAR );

    Does simple RTF escaping of brackets and 8-bit characters. It is also a
    private method.

CAVEATS
    RTF::Group cannot handle circular references. It does not even check for
    them. Which means that

        $g1 = new RTF::Group();
        $g2 = new RTF::Group();

        $g1->append($g2);
        $g2->append($g1);

    will cause *bad things to happen*. Do not do this.

SEE ALSO
    Microsoft Technical Support and Application Note, "Rich Text Format
    (RTF) Specification and Sample Reader Program", Version 1.5.

AUTHOR
    Robert Rothenberg <rrwo@cpan.org>

LICENSE
    Copyright (c) 1999-2000 Robert Rothenberg. All rights reserved. This
    program is free software; you can redistribute it and/or modify it under
    the same terms as Perl itself.

