Your message dated Tue, 21 Jul 2015 21:38:57 +0000
with message-id <e1zhffz-0006oa...@franck.debian.org>
and subject line Bug#670750: fixed in librtf-document-perl 0.64-11
has caused the Debian Bug report #670750,
regarding [PATCH] librtf-document-perl: Helping to update to packaging format 
3.0
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
670750: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=670750
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: librtf-document-perl
Severity: wishlist
Tags: patch

Hi,

The dpatch patch management system has been deprecated for some time. The
Lintian currently flags use of dpatch packages as an error. The new 3.0
packaging format is an improved version which, among other things, contains
patch management built-in. For more information, see:

    http://wiki.debian.org/Projects/DebSrc3.0

I had some free time; see attached patch to migrate to new package
format. Note that all files in debian/patches/* are canocalized to
*.patch.

Let me know if there is anything that needs adjusting or if it is ok
to upload this version in a NMU in case you are working on other
issues needing attention.

Thanks,
Jari

>From 260822b7b4664c70000893443d885b0428f0c2ff Mon Sep 17 00:00:00 2001
From: Jari Aalto <jari.aa...@cante.net>
Date: Sat, 28 Apr 2012 20:19:01 +0300
Subject: [PATCH] format-3.0
Organization: Private
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

Signed-off-by: Jari Aalto <jari.aa...@cante.net>
---
 Document.pm                                        |   88 +-
 debian/changelog                                   |   13 +
 debian/compat                                      |    2 +-
 debian/control                                     |    8 +-
 debian/copyright                                   |    2 +-
 debian/patches/00list                              |    1 -
 debian/patches/10-local-changes.patch              | 2397 ++++++++++++++++++++
 ...ke_it_strict.dpatch => 20-make-it-strict.patch} |    3 -
 debian/patches/series                              |    2 +
 debian/rules                                       |    9 +-
 debian/source/format                               |    1 +
 11 files changed, 2472 insertions(+), 54 deletions(-)
 delete mode 100644 debian/patches/00list
 create mode 100644 debian/patches/10-local-changes.patch
 rename debian/patches/{01_make_it_strict.dpatch => 20-make-it-strict.patch} (99%)
 create mode 100644 debian/patches/series
 create mode 100644 debian/source/format

diff --git a/Document.pm b/Document.pm
index a21b986..4194baf 100644
--- a/Document.pm
+++ b/Document.pm
@@ -14,6 +14,7 @@ $VERSION = "0.64";
 @EXPORT_OK = qw();
 
 use Carp;
+use strict 'vars', 'subs';
 use POSIX qw(floor ceil);
 use Convert::Units::Type 0.33;
 
@@ -129,7 +130,7 @@ sub _prop_decode
 sub _prop_style {
     my ($self, $code, $arg) = @_;
     $code = decode_stylename($arg, '\s222');
-    my $formatting, $style_properties;
+    my ($formatting, $style_properties);
 
     if (defined($code)) {
         $formatting = $self->new_group();
@@ -242,16 +243,16 @@ sub _prop_on {
     'doc_rtf_def'		=> [ 'text',  'defformat',   0, \&_prop_on ],
 
     # --- Page sizes, margins, etc.
-    doc_page_width	=> [ text,  paperw,	0, \&_prop_twips ],
-    doc_page_height	=> [ text,  paperh,	0, \&_prop_twips ],
-    doc_landscape	=> [ text,  landscape,	0, \&_prop_on ],
-    doc_facing	=> [ text,  facingp,	0, \&_prop_on ],
-    doc_margin_left	=> [ text,  margl,		0,  \&_prop_twips ],
-    doc_margin_right	=> [ text,  margr,		0, \&_prop_twips ],
-    doc_margin_top	=> [ text,  margt,		0, \&_prop_twips ],
-    doc_margin_bottom => [ text,  margb, 	0, \&_prop_twips ],
-    doc_margin_mirror=> [ text,  margmirror, 	0, \&_prop_on ],
-    doc_gutter	=> [ text,  gutter, 	0, \&_prop_twips ],
+    doc_page_width	=> [ 'text',  'paperw',	0, \&_prop_twips ],
+    doc_page_height	=> [ 'text',  'paperh',	0, \&_prop_twips ],
+    doc_landscape	=> [ 'text',  'landscape',	0, \&_prop_on ],
+    doc_facing	=> [ 'text',  'facingp',	0, \&_prop_on ],
+    doc_margin_left	=> [ 'text',  'margl',		0,  \&_prop_twips ],
+    doc_margin_right	=> [ 'text',  'margr',		0, \&_prop_twips ],
+    doc_margin_top	=> [ 'text',  'margt',		0, \&_prop_twips ],
+    doc_margin_bottom => [ 'text',  'margb', 	0, \&_prop_twips ],
+    doc_margin_mirror=> [ 'text',  'margmirror', 	0, \&_prop_on ],
+    doc_gutter	=> [ 'text',  'gutter', 	0, \&_prop_twips ],
 
     # --- Hyphenation
     doc_hyphen_auto	=> [ 'text', 'hyphauto', 0,  \&_prop_onoff ],
@@ -260,10 +261,10 @@ sub _prop_on {
     doc_hyphen_zone	=> [ 'text', 'hyphhotz', 0,  \&_prop_twips ],
 
     # --- Views
-    doc_view_scale	=> [ text,  viewscale,   0, \&_prop_raw  ],
-    doc_view_zoom	=> [ text, { none=>'viewzk0', 'full-page'=>'viewzk1',
+    doc_view_scale	=> [ 'text',  'viewscale',   0, \&_prop_raw  ],
+    doc_view_zoom	=> [ 'text', { none=>'viewzk0', 'full-page'=>'viewzk1',
       'best-fit'=>'viewzk1' },  0, \&_prop_decode ],
-    doc_view_caption	=> [ text, windowcaption, 1, , \&_prop_pcdata ],
+    doc_view_caption	=> [ 'text', 'windowcaption', 1, , \&_prop_pcdata ],
     'doc_view_mode'	=> [ 'text', { 'none'=>'viewkind0', 'layout'=>'viewkind1',
       'outline'=>'viewkind2', 'master'=>'viewkind3',
 
@@ -276,7 +277,7 @@ sub _prop_on {
     'doc_charset'		=> [ 'charset' ],
 
     # --- Widow/orphan controls
-    doc_widow_cntrl	=> [ text,  widowctrl,   0, \&_prop_on ],
+    doc_widow_cntrl	=> [ 'text',  'widowctrl',   0, \&_prop_on ],
 
     # --- Tabs
     tabs_default	=> [ 'text',  'deftab', 	0, \&_prop_twips ],
@@ -296,14 +297,14 @@ sub _prop_on {
       'page'=>'sbkpage', 'even'=>'sbkeven', 'odd'=>'sbkodd'}, 0, \&_prop_decode ],
 
     # --- Columns
-    col		=> [ text,  'colulmn',  	0, \&_prop_on ],
-    col_soft		=> [ text,  'softcol',  	0, \&_prop_on ],
-    col_num		=> [ text,  'cols',  	0, \&_prop_raw ],
-    col_space		=> [ text,  'colsx', 	0, \&_prop_twips ],
-    col_select	=> [ text,  'colno', 	0, \&_prop_raw ],
-    col_padding_right => [ text, 'colsr', 	0, \&_prop_twips ],
-    col_width 	=> [ text,  'colw',		0, \&_prop_twips ],
-    col_line		=> [ text,  'linebetcol',	0, \&_prop_on ],
+    col		=> [ 'text',  'colulmn',  	0, \&_prop_on ],
+    col_soft		=> [ 'text',  'softcol',  	0, \&_prop_on ],
+    col_num		=> [ 'text',  'cols',  	0, \&_prop_raw ],
+    col_space		=> [ 'text',  'colsx', 	0, \&_prop_twips ],
+    col_select	=> [ 'text',  'colno', 	0, \&_prop_raw ],
+    col_padding_right => [ 'text', 'colsr', 	0, \&_prop_twips ],
+    col_width 	=> [ 'text',  'colw',		0, \&_prop_twips ],
+    col_line		=> [ 'text',  'linebetcol',	0, \&_prop_on ],
 
     'page_brk'	=> [ 'text', 'page', 	0, \&_prop_on ],
     'page_softbrk'	=> [ 'text', 'softpage',	0, \&_prop_on ],
@@ -316,7 +317,7 @@ sub _prop_on {
 
     # --- Alignment
     'par_align'	=> [ 'text', { left=>'ql', right=>'qr', center=>'qc', justify=>'qj' },  0, \&_prop_decode ],
-    'sec_vert_align'	=> [ 'text', { top=>vertalt, bottom=>vertalb, center=>vertalc },  0, \&_prop_decode ],
+    'sec_vert_align'	=> [ 'text', { top=>'vertalt', bottom=>'vertalb', center=>'vertalc' },  0, \&_prop_decode ],
 
     # --- Indentation
     'par_indent_first'	=> [ 'text', 'fi', 	0, \&_prop_twips ],
@@ -378,7 +379,7 @@ sub _prop_on {
     'par_hyphen'		=> [ 'text', 'hyphpar', 	0,  \&_prop_onoff ],
 
     # --- Widow/orphan controls
-    'par_widow_cntrl' 	=> [ text, { 0=>nowidctlpar, 1=>widctlpar }, 0, \&_prop_decode ],
+    'par_widow_cntrl' 	=> [ 'text', { 0=>'nowidctlpar', 1=>'widctlpar' }, 0, \&_prop_decode ],
     'par_intact'		=> [ 'text', 'keep',  	0, \&_prop_on ],
     'par_keep_next'		=> [ 'text', 'keepn',	0, \&_prop_on ],
 
@@ -397,9 +398,9 @@ sub set_properties
     my $self = shift;
 
     my $table = shift,
-       $settings = shift,
-       $destination = shift;
-    my ($property, $value, $where, $what, $arg, $default);
+    my $settings = shift,
+    my $destination = shift;
+    my ($property, $value, $where, $what, $group, $arg, $default);
 
     local ($_);
 
@@ -426,7 +427,7 @@ sub set_properties
                 {
                     if ($group) {
                         my $subgroup = $self->add_group($where);
-                        $self->add_raw ($subroup, @controls );
+                        $self->add_raw ($subgroup, @controls );
                     } else {
                         $self->add_raw ($where, @controls );
                     }
@@ -469,7 +470,7 @@ sub import {
     my $self = shift;
     $self->set_properties (\%DOCINFO, @_);
 
-    $self->splice_raw ($self->{DOCUMENT}, 1, 1, "\\".$self->{charset});
+    $self->splice_raw ($self->{DOCUMENT}, 1, 1, "\\".$self->{charset}) if ( defined $self->{charset} );
 
     # --- Insert creation time in Information Group
     if ($self->{creatim})
@@ -498,7 +499,7 @@ sub new
 }
 
 sub emit_group {
-    local ($el, $data);
+    my ($el, $data);
 
     unless (@_) {
         return undef;
@@ -508,7 +509,7 @@ sub emit_group {
 
     foreach $el (@_)
     {
-        if (ref($el) eq ARRAY) {
+        if (ref($el) eq "ARRAY") {
             $data .= emit_group(@$el);
         } else {
             if (($el !~ m/^[\\\;\{\}]/) and (substr($data, length($data)-1) !~ m/[\}\{\s]/)) {
@@ -548,7 +549,7 @@ sub add_font
     my $self = shift;
 
     my $name = shift,
-       $attributes = shift;
+    my $attributes = shift;
 
     my $class = $FONTCLASSES{${$attributes}{family}};
 
@@ -580,7 +581,8 @@ sub add_font
 
     $self->add_raw ($fattr, escape_simple($name) );
 
-    my @alternates = @{${$attributes}{alternates}};
+    my @alternates = ();
+       @alternates = @{${$attributes}{alternates}} if ( defined @{${$attributes}{alternates}} );
     if (@alternates) {
         while ($_ = shift @alternates) {
             $self->add_raw ($fattr, [ '\*\falt '.escape_simple($_) ] );
@@ -630,7 +632,7 @@ sub add_style
         $self->add_raw ( $self->{styletbl}, '\stylesheet');
     }
 
-    $type = ${$attributes}{type} || "paragraph";
+    my $type = ${$attributes}{type} || "paragraph";
     my $code = $STYLETYPES{$type};
     unless (defined($code)) {
         carp "Don\'t know how to handle a \`$type\' style";
@@ -654,7 +656,7 @@ sub add_style
         if (defined(${$attributes}{next}));
 
     my $sbasedon = ${$attributes}{basedon} || "none",
-       $snext    = ${$attributes}{next}    || "self";
+    my $snext    = ${$attributes}{next}    || "self";
 
     $sbasedon = decode_stylename($sbasedon, $style);
     $snext    = decode_stylename($snext, $style);
@@ -802,7 +804,7 @@ sub splice_raw # splice a raw value into a section
     my $position = shift;
     my $length = shift;
 
-    splice @{$section}, $position, $length, @_;
+    splice @{$section}, $position, $length, @_ ;
 }
 
 sub add_raw # add a raw value to a section
@@ -855,16 +857,16 @@ sub add_text {
 
     while ($arg = shift) {
         $rarg = ref($arg);
-        if ($rarg eq HASH)
+        if ($rarg eq "HASH")
         {
             $self->set_properties (\%PROPERTIES, $arg, $group);
         }
-        elsif ($rarg eq ARRAY)
+        elsif ($rarg eq "ARRAY")
         {
             my $subgroup = $self->add_group($group);
             $self->add_text ($subgroup, @{$arg} );
         }
-        elsif ($rarg eq SCALAR)
+        elsif ($rarg eq "SCALAR")
         {
             $self->add_text (${$arg});
         }
@@ -1192,5 +1194,9 @@ 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.
 
-=cut
+=head1 FIXES
 
+Some bugs have been fixed by nmag only <n...@softhome.net>, now
+the code is clean and under strict directives.
+
+=cut
diff --git a/debian/changelog b/debian/changelog
index 288119d..759910d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,16 @@
+librtf-document-perl (0.64-10.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Remove deprecated dpatch and upgrade to packaging format "3.0 quilt".
+  * Update to Standards-Version to 3.9.3 and debhelper to 9.
+  * Add required build-arch and build-indep targets to rules file.
+  * Fix copyright-refers-to-symlink-license (Lintian).
+  * Patches:
+    - Number patches
+    - Patch 10 is new; in-line changes to original files.
+
+ -- Jari Aalto <jari.aa...@cante.net>  Sat, 28 Apr 2012 20:15:05 +0300
+
 librtf-document-perl (0.64-10) unstable; urgency=low
 
   * obvious dependency problems fixed
diff --git a/debian/compat b/debian/compat
index b8626c4..ec63514 100644
--- a/debian/compat
+++ b/debian/compat
@@ -1 +1 @@
-4
+9
diff --git a/debian/control b/debian/control
index 09612d9..0ff010b 100644
--- a/debian/control
+++ b/debian/control
@@ -2,13 +2,13 @@ Source: librtf-document-perl
 Section: perl
 Priority: extra
 Maintainer: Krzysztof Krzyzaniak (eloy) <e...@debian.org>
-Build-Depends: debhelper (>> 4.0.0)
-Build-Depends-Indep: perl5, libconvert-units-perl (>= 0.43), dpatch
-Standards-Version: 3.6.2
+Build-Depends: debhelper (>= 9)
+Build-Depends-Indep: perl5, libconvert-units-perl (>= 0.43)
+Standards-Version: 3.9.3
 
 Package: librtf-document-perl
 Architecture: all
-Depends: ${perl:Depends}, libconvert-units-perl (>= 0.43)
+Depends: ${misc:Depends}, ${perl:Depends}, libconvert-units-perl (>= 0.43)
 Description: Perl extension for generating Rich Text (RTF) Files
  RTF::Document is a module for generating Rich Text Format (RTF) 
  documents that can be used by most text converters and word processors.
diff --git a/debian/copyright b/debian/copyright
index fa75d51..313fe04 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -18,5 +18,5 @@ it under the terms of either:
    b) the "Artistic License" which comes with Perl.
 			     
 On Debian GNU/Linux systems, the complete text of the GNU General
-Public License can be found in /usr/share/common-licenses/GPL' and
+Public License can be found in /usr/share/common-licenses/GPL-2' and
 the Artistic Licence in /usr/share/common-licenses/Artistic'.
diff --git a/debian/patches/00list b/debian/patches/00list
deleted file mode 100644
index f74dee1..0000000
--- a/debian/patches/00list
+++ /dev/null
@@ -1 +0,0 @@
-01_make_it_strict
diff --git a/debian/patches/10-local-changes.patch b/debian/patches/10-local-changes.patch
new file mode 100644
index 0000000..71e24b8
--- /dev/null
+++ b/debian/patches/10-local-changes.patch
@@ -0,0 +1,2397 @@
+diff --git a/Document.pm b/Document.pm
+index 2912269..a21b986 100644
+--- a/Document.pm
++++ b/Document.pm
+@@ -1,1196 +1,1196 @@
+-package RTF::Document;
+-require 5.005;
+-require Exporter;
+-
+-use vars qw(
+-    $VERSION
+-    %DOCINFO %PROPERTIES
+-    %FONTCLASSES %FONTPITCH %COLORNAMES %STYLETYPES %NUMSTYLES
+-);
+-$VERSION = "0.64";
+-
+-@ISA = qw(Exporter);
+-@EXPORT = qw();
+-@EXPORT_OK = qw();
+-
+-use Carp;
+-use POSIX qw(floor ceil);
+-use Convert::Units::Type 0.33;
+-
+-%NUMSTYLES = (
+-    '1' => '\pndec',
+-    'a' => '\pnlcltr',
+-    'i' => '\pnlcrm',
+-    'A' => '\pnucltr',
+-    'I' => '\pnucrm',
+-    '1st' => '\pnord'
+-);
+-
+-sub _prop_list
+-{
+-    my ($self, $code, $properties) = @_;
+-    my ($result, $level, $style);
+-
+-    if ($properties eq "off") {
+-        return '\pard';
+-    }
+-
+-    $result = $self->new_group( '\*', '\pn' );
+-
+-    ${$properties}{level} = ${$properties}{style}, if (${$properties}{style} eq "bullet");
+-
+-    if (${$properties}{level}) {
+-        $level = ${$properties}{level};
+-        $level = "blt", if ($level eq "bullet");
+-        if ((($level<1) or ($level>11)) and ($level ne "blt"))
+-        {
+-            carp "List level \`$level\' is out of range";
+-            $level = 'body';
+-        }
+-    } else {
+-        $level = 'body';
+-    }
+-
+-    $self->add_raw ($result, '\pnlvl'.$level);
+-
+-    if ($level eq "body")  {
+-        $style = $NUMSTYLES{${$properties}{style}} || '\pndec';
+-        $self->add_raw ($result, $style);
+-    }
+-
+-    if (defined(${$properties}{font}))
+-    {
+-       $self->add_raw ($result, '\pnf'.${$properties}{font});
+-    }
+-
+-    if (defined(${$properties}{color}))
+-    {
+-       $self->add_raw ($result, '\pncf'.${$properties}{color});
+-    }
+-
+-    if (defined(${$properties}{before}))
+-    {
+-       my $group = $self->add_group($result);
+-       $self->add_raw ($group, '\pntxtb '.escape_simple(${$properties}{before}) );
+-    }
+-
+-    if (defined(${$properties}{after}))
+-    {
+-       my $group = $self->add_group($result);
+-       $self->add_raw ($group, '\pntxta '.escape_simple(${$properties}{after}) );
+-    }
+-
+-    if (${$properties}{across})
+-    {
+-       $self->add_raw ($result, '\pnacross');
+-    }
+-
+-    if (defined(${$properties}{indent}))
+-    {
+-       $self->add_raw ($result, '\pnindent'.POSIX::floor(
+-         Convert::Units::Type::convert(${$properties}{indent}, "twips")
+-       ));
+-    }
+-
+-    if (defined(${$properties}{space}))
+-    {
+-       $self->add_raw ($result, '\pnsp'.POSIX::floor(
+-         Convert::Units::Type::convert(${$properties}{space}, "twips")
+-       ));
+-    }
+-
+-    if (${$properties}{hang})
+-    {
+-       $self->add_raw ($result, '\pnhang');
+-    }
+-
+-    if (defined(${$properties}{start}))
+-    {
+-       $self->add_raw ($result, '\pnstart'.${$properties}{start});
+-    }
+-
+-
+-    return ($result);
+-}
+-
+-# $arg is a key to RTF control in hash value
+-sub _prop_decode
+-{
+-    my ($self, $hash, $arg) = @_;
+-    my $result = ${$hash}{$arg};
+-
+-    unless (defined($result)) {
+-        carp "Don\'t know how to handle value \`$arg\'";
+-    }
+-
+-    return ("\\".$result);
+-}
+-
+-sub _prop_style {
+-    my ($self, $code, $arg) = @_;
+-    $code = decode_stylename($arg, '\s222');
+-    my $formatting, $style_properties;
+-
+-    if (defined($code)) {
+-        $formatting = $self->new_group();
+-        %{$style_properties} = %{$self->{styles}->{$code}};
+-
+-        if (${$style_properties}{secd}) {
+-            $self->add_raw($formatting, '\secd');
+-            delete ${$style_properties}{secd};
+-        }
+-        if (${$style_properties}{pard}) {
+-            $self->add_raw($formatting, '\pard');
+-            delete ${$style_properties}{pard};
+-        }
+-        if (${$style_properties}{plain}) {
+-            $self->add_raw($formatting, '\plain');
+-            delete ${$style_properties}{plain};
+-        }
+-
+-        $self->set_properties( \%PROPERTIES, $style_properties, $formatting);
+-        unless (@{$formatting}) {
+-            carp "Style \`$arg\' is not defined";
+-            $code = decode_stylename("none");
+-        }
+-    }
+-    return ($code, @{$formatting} );
+-}
+-
+-# $arg is a unit of type (points, picas, inches) converted to twips
+-sub _prop_twips {
+-    my ($self, $code, $arg) = @_;
+-    return ("\\".$code.POSIX::floor(Convert::Units::Type::convert($arg, "twips")));
+-}
+-
+-# $arg is a unit of type (points, picas, inches) converted to half-points
+-sub _prop_halfpts {
+-    my ($self, $code, $arg) = @_;
+-    return ("\\".$code.POSIX::floor(Convert::Units::Type::convert($arg, "half-points")));
+-}
+-
+-# $arg is a string (which may need to be escaped)
+-sub _prop_pcdata {
+-    my ($self, $code, $arg) = @_;
+-    $arg =~ s/([\\\{\}])/\\$1/g;
+-    return ("\\".$code, escape_simple($arg));
+-}
+-
+-# $arg is a raw value
+-sub _prop_raw {
+-    my ($self, $code, $arg) = @_;
+-    return ("\\".$code.$arg);
+-}
+-
+-# $arg is a an on/off indicator (0 = off, NZ = on)
+-sub _prop_onoff {
+-    my ($self, $code, $arg) = @_;
+-    if ($arg)
+-    {
+-        return ("\\".$code);
+-    }
+-    else
+-    {
+-        return ("\\".$code."0");
+-    }
+-}
+-
+-# $arg is a an emit/don't emit indicator (0 = don't emit control, NZ = emit)
+-sub _prop_on {
+-    my ($self, $code, $arg) = @_;
+-    if ($arg)
+-    {
+-        return ("\\".$code);
+-    }
+-    else
+-    {
+-        return undef;
+-    }
+-}
+-
+-# Synopsis of %DOCINFO and %PROPERTIES
+-#   property => [ where, control, group, function ]
+-#     property = name of the property
+-#     where    = what section of the document this control is usually applied to
+-#     control	 = the control word used (if a hash, how to decode various controls)
+-#     group    = if non-zero, emit this as part of a group
+-#     function = what function to use to process this property
+-# Most properties follow the following naming scheme:
+-#  doc = document-wide properties (should be set only once)
+-#  sec = section properties
+-#  col = column properties (within a section)
+-#  par = paragraph properties
+-
+-%DOCINFO = (
+-    # --- Document summary information
+-    'doc_title'		=> [ 'info',  'title', 	1, \&_prop_pcdata ],
+-    'doc_author'		=> [ 'info',  'author',	1, \&_prop_pcdata ],
+-    'doc_subject'		=> [ 'info',  'subject',	1, \&_prop_pcdata ],
+-    'doc_manager'		=> [ 'info',  'manager',	1, \&_prop_pcdata ],
+-    'doc_company'		=> [ 'info',  'company',	1, \&_prop_pcdata ],
+-    'doc_operator'		=> [ 'info',  'operator',	1, \&_prop_pcdata ],
+-    'doc_category'		=> [ 'info',  'category',	1, \&_prop_pcdata ],
+-    'doc_keywords'		=> [ 'info',  'keywords',	1, \&_prop_pcdata ],
+-    'doc_summary'		=> [ 'info',  'doccomm',	1, \&_prop_pcdata ],
+-    'doc_comment'		=> [ 'text',  '*\comment',	1, \&_prop_pcdata ],
+-    'doc_base_href'		=> [ 'info',  'hlinkbase', 	1, \&_prop_pcdata ],
+-    'doc_version'		=> [ 'info',  'version',	0, \&_prop_raw  ],
+-    'doc_time_created'	=> [ 'creatim' ],
+-
+-    'doc_from_text'		=> [ 'text',  'fromtext',    0, \&_prop_on ],
+-    'doc_make_backup'	=> [ 'text',  'makebackup',  0, \&_prop_on ],
+-    'doc_rtf_def'		=> [ 'text',  'defformat',   0, \&_prop_on ],
+-
+-    # --- Page sizes, margins, etc.
+-    doc_page_width	=> [ text,  paperw,	0, \&_prop_twips ],
+-    doc_page_height	=> [ text,  paperh,	0, \&_prop_twips ],
+-    doc_landscape	=> [ text,  landscape,	0, \&_prop_on ],
+-    doc_facing	=> [ text,  facingp,	0, \&_prop_on ],
+-    doc_margin_left	=> [ text,  margl,		0,  \&_prop_twips ],
+-    doc_margin_right	=> [ text,  margr,		0, \&_prop_twips ],
+-    doc_margin_top	=> [ text,  margt,		0, \&_prop_twips ],
+-    doc_margin_bottom => [ text,  margb, 	0, \&_prop_twips ],
+-    doc_margin_mirror=> [ text,  margmirror, 	0, \&_prop_on ],
+-    doc_gutter	=> [ text,  gutter, 	0, \&_prop_twips ],
+-
+-    # --- Hyphenation
+-    doc_hyphen_auto	=> [ 'text', 'hyphauto', 0,  \&_prop_onoff ],
+-    doc_hyphen_caps	=> [ 'text', 'hyphcaps', 0,  \&_prop_onoff ],
+-    doc_hyphen_lines	=> [ 'text', 'hyphconsec', 0,  \&_prop_onoff ],
+-    doc_hyphen_zone	=> [ 'text', 'hyphhotz', 0,  \&_prop_twips ],
+-
+-    # --- Views
+-    doc_view_scale	=> [ text,  viewscale,   0, \&_prop_raw  ],
+-    doc_view_zoom	=> [ text, { none=>'viewzk0', 'full-page'=>'viewzk1',
+-      'best-fit'=>'viewzk1' },  0, \&_prop_decode ],
+-    doc_view_caption	=> [ text, windowcaption, 1, , \&_prop_pcdata ],
+-    'doc_view_mode'	=> [ 'text', { 'none'=>'viewkind0', 'layout'=>'viewkind1',
+-      'outline'=>'viewkind2', 'master'=>'viewkind3',
+-
+-
+-
+-
+-      'normal'=>'viewkind4', 'online'=>'viewkind5'}, 0, \&_prop_decode ],
+-
+-    # --- Character set
+-    'doc_charset'		=> [ 'charset' ],
+-
+-    # --- Widow/orphan controls
+-    doc_widow_cntrl	=> [ text,  widowctrl,   0, \&_prop_on ],
+-
+-    # --- Tabs
+-    tabs_default	=> [ 'text',  'deftab', 	0, \&_prop_twips ],
+-
+-);
+-
+-%PROPERTIES = (
+-
+-    # --- New section, paragraph, line
+-    'sec'		=> [ 'text', 'sect', 	0, \&_prop_on ],
+-    'par'		=> [ 'text', 'par', 		0, \&_prop_on ],
+-    'line'		=> [ 'text', 'line', 	0, \&_prop_on ],
+-    'line_soft'	=> [ 'text', 'softline', 	0, \&_prop_on ],
+-
+-    # --- Sections....
+-    'sec_brk'		=> [ 'text', { 'none'=>'sbknone', 'column'=>'sbkcol',
+-      'page'=>'sbkpage', 'even'=>'sbkeven', 'odd'=>'sbkodd'}, 0, \&_prop_decode ],
+-
+-    # --- Columns
+-    col		=> [ text,  'colulmn',  	0, \&_prop_on ],
+-    col_soft		=> [ text,  'softcol',  	0, \&_prop_on ],
+-    col_num		=> [ text,  'cols',  	0, \&_prop_raw ],
+-    col_space		=> [ text,  'colsx', 	0, \&_prop_twips ],
+-    col_select	=> [ text,  'colno', 	0, \&_prop_raw ],
+-    col_padding_right => [ text, 'colsr', 	0, \&_prop_twips ],
+-    col_width 	=> [ text,  'colw',		0, \&_prop_twips ],
+-    col_line		=> [ text,  'linebetcol',	0, \&_prop_on ],
+-
+-    'page_brk'	=> [ 'text', 'page', 	0, \&_prop_on ],
+-    'page_softbrk'	=> [ 'text', 'softpage',	0, \&_prop_on ],
+-
+-    # --- Forms....
+-    'sec_unlock'	=> [ 'text', 'sectunlocked', 	0, \&_prop_on ],
+-
+-    # --- Footsnotes, endnotes stuff
+-    'sec_endnotes_here' => [ 'text', 'endnhere',	0, \&_prop_on ],
+-
+-    # --- Alignment
+-    'par_align'	=> [ 'text', { left=>'ql', right=>'qr', center=>'qc', justify=>'qj' },  0, \&_prop_decode ],
+-    'sec_vert_align'	=> [ 'text', { top=>vertalt, bottom=>vertalb, center=>vertalc },  0, \&_prop_decode ],
+-
+-    # --- Indentation
+-    'par_indent_first'	=> [ 'text', 'fi', 	0, \&_prop_twips ],
+-    'par_indent_left'	=> [ 'text', 'li', 	0, \&_prop_twips ],
+-    'par_indent_right'	=> [ 'text', 'ri', 	0, \&_prop_twips ],
+-    'par_outline_level'	=> [ 'text', 'outlinelevel', 0, \&_prop_raw ],
+-
+-    'par_number_text'	=> [ 'text', 'pntext', 1, \&_prop_pcdata ],
+-    'par_number'		=> [ 'text', 'pn', 0, \&_prop_list ],
+-
+-    # --- Style
+-    'style'		=> [ 'text', 's', 		0, \&_prop_style ],
+-    'style_default'	=> [ 'text', { 'character'=>'plain', 'paragraph'=>'pard',
+-        'section'=>'secd', 'row'=>'trowd', 'cell'=>'tcelld' },  0, \&_prop_decode ],
+-
+-    # --- Paragraph spacing
+-    'par_space_before'	=> [ 'text', 'sb',	0,  \&_prop_twips ],
+-    'par_space_after'	=> [ 'text', 'sa',	0,  \&_prop_twips  ],
+-    'par_space_lines'	=> [ 'text', 'sl',	0,  \&_prop_raw  ],
+-    'par_space_lines_mult'	=> [ 'text', 'slmult', 0,  \&_prop_raw  ],
+-
+-    # --- Character formatting
+-    'bold'		=> [ 'text',  'b',		0,  \&_prop_onoff ],
+-    'italic'		=> [ 'text',  'i',		0,  \&_prop_onoff ],
+-    'caps'		=> [ 'text',  'caps',	0,  \&_prop_onoff ],
+-    'caps_small'	=> [ 'text',  'scaps',	0,  \&_prop_onoff ],
+-    'underline'	=> [ 'text', { 'off'=>'ul0', 'continuous'=>'ul', 'dotted'=>'uld',
+-        'dash'=>'uldash', 'dot-dash'=>'uldashd', 'dot-dot-dash'=>'uldashdd',
+-        'double'=>'ulb', 'none'=>'ulnone', 'thick'=>'ulth', 'word'=>'ulw',
+-        'wave'=>'ulwave' },  0, \&_prop_decode ],
+-    'hidden'			=> [ 'text', 'v',		0,  \&_prop_onoff ],
+-
+-    # --- Colors
+-    'color_foreground' 	=> [ 'text', 'cf',		0, \&_prop_raw ],
+-    'color_background' 	=> [ 'text', 'cb',		0, \&_prop_raw ],
+-    'highlight'		=> [ 'text', 'highlight',	0, \&_prop_raw ],
+-
+-    # --- Fonts
+-    'font'			=> [ 'text', 'f', 		0, \&_prop_raw ],
+-    'font_size'		=> [ 'text', 'fs',		0, \&_prop_halfpts ],
+-    'font_scale'		=> [ 'text', 'charscalex', 	0,  \&_prop_raw  ],
+-
+-    # --- Page sizes, margins, etc.
+-    'sec_page_width'		=> [ 'text', 'pgwsxn',	0, \&_prop_twips ],
+-    'sec_page_height' 	=> [ 'text', 'pghsxn',	0, \&_prop_twips ],
+-    'sec_landscape'		=> [ 'text', 'lndscpsxn',	0, \&_prop_on ],
+-    'sec_margin_left' 	=> [ 'text', 'marglsxn',	0, \&_prop_twips ],
+-    'sec_margin_right' 	=> [ 'text', 'margrsxn',	0, \&_prop_twips ],
+-    'sec_margin_top'	 	=> [ 'text', 'margtsxn',	0, \&_prop_twips ],
+-    'sec_margin_bottom' 	=> [ 'text', 'margbsxn', 	0, \&_prop_twips ],
+-    'sec_margin_mirror' 	=> [ 'text', 'margmirsxn',	0, \&_prop_on ],
+-    'sec_gutter'		=> [ 'text', 'guttersxn', 	0, \&_prop_twips ],
+-
+-    'sec_title_pg' 		=> [ 'text', 'titlepg', 	0, \&_prop_on ],
+-    'sec_header_margin' 	=> [ 'text', 'headery', 	0, \&_prop_twips ],
+-    'sec_footer_margin' 	=> [ 'text', 'footery', 	0, \&_prop_twips ],
+-
+-    # --- Hyphenation
+-    'par_hyphen'		=> [ 'text', 'hyphpar', 	0,  \&_prop_onoff ],
+-
+-    # --- Widow/orphan controls
+-    'par_widow_cntrl' 	=> [ text, { 0=>nowidctlpar, 1=>widctlpar }, 0, \&_prop_decode ],
+-    'par_intact'		=> [ 'text', 'keep',  	0, \&_prop_on ],
+-    'par_keep_next'		=> [ 'text', 'keepn',	0, \&_prop_on ],
+-
+-    'par_pgbrk_before' 	=> [ 'text', 'pagebb',	0, \&_prop_on ],
+-
+-    # --- Page numbering
+-    'pg_num_start' 		=> [ 'text', 'pgnstart',	0, \&_prop_raw ],
+-    'pg_num_cont'		=> [ 'text', 'pgncont',	0, \&_prop_on ],
+-    'pg_num_restart' 	=> [ 'text', 'pgnrestart',	0, \&_prop_on ],
+-
+-    'sec_title_pg' 		=> [ 'text', 'titlepg', 	0, \&_prop_on ]
+-);
+-
+-sub set_properties
+-{
+-    my $self = shift;
+-
+-    my $table = shift,
+-       $settings = shift,
+-       $destination = shift;
+-    my ($property, $value, $where, $what, $arg, $default);
+-
+-    local ($_);
+-
+-    foreach $property (keys %{$settings}) {   
+-        if (defined(${$table}{$property}))
+-        {
+-            ($where, $what, $group, $default, $arg) = @{${$table}{$property}};
+-
+-            if (defined($destination))
+-            {
+-                carp "\`$property\' is not a section, paragraph or character property",
+-                    if ($where ne "text");
+-                $where = $destination;
+-            } else {
+-                $where = $self->{$where}, if (defined($what));
+-            }
+-
+-            if (defined($what))
+-            {
+-                $value = ${$settings}{$property};
+-                my @controls = $self->$default($what, $value, $arg);
+-
+-                if (@controls)
+-                {
+-                    if ($group) {
+-                        my $subgroup = $self->add_group($where);
+-                        $self->add_raw ($subroup, @controls );
+-                    } else {
+-                        $self->add_raw ($where, @controls );
+-                    }
+-                }                
+-            } else {
+-                $self->{$where} = ${$settings}{$property};
+-            }
+-
+-        } else {
+-            carp "Don\'t know how to handle property: \`$property\'";
+-        }
+-    }
+-}
+-
+-sub initialize
+-{
+-    my $self = shift;
+-    $self->{charset} 	= "ansi";	# Character Set
+-
+-    # --- Document Header
+-    $self->{DOCUMENT}	= $self->new_group( '\rtf', $self->{charset} );
+-
+-    $self->{fonttbl}		= $self->add_group($self->{DOCUMENT});
+-    $self->{fontCnt}		= 0;
+-
+-    $self->{colortbl}	= $self->add_group($self->{DOCUMENT});
+-    $self->{colorCnt}	= 0;	# count of colors in table
+-
+-    $self->{styletbl} 	= $self->add_group($self->{DOCUMENT});
+-    $self->{styleCnt}	= 0;	# count of styles defined
+-
+-    $self->{text} 		= $self->add_group($self->{DOCUMENT});
+-
+-    $self->{info} 		= $self->add_group();
+-    $self->add_raw		( $self->{info}, '\info' );
+-    $self->{creatim} 	= time();
+-}
+-
+-sub import {
+-    my $self = shift;
+-    $self->set_properties (\%DOCINFO, @_);
+-
+-    $self->splice_raw ($self->{DOCUMENT}, 1, 1, "\\".$self->{charset});
+-
+-    # --- Insert creation time in Information Group
+-    if ($self->{creatim})
+-    {
+-        my ($ss, $mn, $hr, $dd, $mm, $yy) = localtime($self->{creatim});
+-        $yy+=1900; $mm++;
+-
+-        my $creatim = $self->add_group($self->{info});
+-
+-        $self->add_raw( $creatim,  '\creatim',
+-            "\\yr$yy", "\\mo$mm", "\\dy$dd", "\\hr$hr", "\\min$mn", "\\sec$ss"
+-        );
+-        $self->{creatim} = 0;
+-    };
+-}
+-
+-sub new
+-{
+-    my $this = shift;
+-    my $class = ref($this) || $this;
+-    my $self = {};
+-    bless $self, $class;
+-    $self->initialize();
+-    $self->import(@_);
+-    return $self;
+-}
+-
+-sub emit_group {
+-    local ($el, $data);
+-
+-    unless (@_) {
+-        return undef;
+-    }
+-
+-    $data = "\{";
+-
+-    foreach $el (@_)
+-    {
+-        if (ref($el) eq ARRAY) {
+-            $data .= emit_group(@$el);
+-        } else {
+-            if (($el !~ m/^[\\\;\{\}]/) and (substr($data, length($data)-1) !~ m/[\}\{\s]/)) {
+-                $data .= " ";
+-            }
+-            $data .= $el;
+-        }
+-    }
+-    $data .= "\}";
+-    return $data;
+-
+-}
+-
+-
+-%FONTCLASSES = (
+-    'swiss'	=> 'swiss',
+-    'sans-serif' => 'swiss',
+-    'roman'	=> 'roman',
+-    'serif'	=> 'roman',
+-    'modern'	=> 'modern',
+-    'monospace' => 'modern',
+-    'script'	=> 'script',
+-    'decor'	=> 'decor',
+-    'fantasy'	=> 'decor',
+-    'tech'	=> 'tech',
+-    'symbol'	=> 'tech',
+-    'bidi'	=> 'bidi'
+-);
+-%FONTPITCH = (
+-    'default' => 0,
+-    'fixed'  	=> 1,
+-    'variable' => 2
+-);
+-sub add_font
+-{
+-    local ($_);
+-    my $self = shift;
+-
+-    my $name = shift,
+-       $attributes = shift;
+-
+-    my $class = $FONTCLASSES{${$attributes}{family}};
+-
+-    unless (defined($class)) {
+-        $class = "nil";
+-        carp "Unknown font family \`${$attributes}{family}\'";
+-    }
+-
+-    unless ($self->{fontCnt}) {
+-        $self->add_raw ($self->{fonttbl}, '\fonttbl');
+-        $self->splice_raw ($self->{DOCUMENT}, 2, 0, "\\deff".$self->{fontCnt});
+-    }
+-
+-    my $fattr = $self->add_group($self->{fonttbl});
+-
+-    $self->add_raw ($fattr, ('\f'.$self->{fontCnt}, '\f'.$class) );
+-
+-    if (defined(my $pitch = ${$attributes}{pitch}))
+-    {
+-        $self->add_raw ($fattr, '\fprq'. ($FONTPITCH{ $pitch }
+-            or carp "Don\'t know how to handle \`pitch => $pitch\'" )
+-        );
+-    }
+-
+-    if (defined(my $actual = ${$attributes}{name})) # non-tagged name (is this correct?)
+-    {
+-        $self->add_raw ($fattr, ['\*\fname '.escape_simple($actual) ] );
+-    }
+-
+-    $self->add_raw ($fattr, escape_simple($name) );
+-
+-    my @alternates = @{${$attributes}{alternates}};
+-    if (@alternates) {
+-        while ($_ = shift @alternates) {
+-            $self->add_raw ($fattr, [ '\*\falt '.escape_simple($_) ] );
+-        }
+-    }
+-
+-    $self->add_raw ($fattr, ';' );
+-
+-    if (${$attributes}{default}) {
+-        carp "Default font redefined",
+-            if (@{$self->{DOCUMENT}}[2] ne "\\deff0");
+-            @{$self->{DOCUMENT}}[2] = "\\deff".$self->{fontCnt};
+-    }
+-
+-    return $self->{fontCnt}++;
+-}
+-
+-sub decode_stylename
+-{
+-    my $name = shift;
+-    my $current = shift || '\s0';
+-
+-    $current =~ m/^\\[cd]?s(\d+)/;
+-    my ($next, $last) = ($1+1, $1-1);
+-    $last = 222, if ($last<0);
+-   
+-    return '\s222', if ($name eq "none");
+-    return '\s0', if ($name eq "default");
+-    return $current, if ($name eq "self");
+-    return '\s'.$next, if ($name eq "next");
+-    return '\s'.$last, if ($name eq "last");
+-    return $name;
+-}
+-
+-%STYLETYPES = (
+-    'character' => '\*\cs',
+-    'paragraph' => '\s',
+-    'section' => '\ds'
+-);
+-
+-sub add_style
+-{
+-    my $self = shift;
+-    my ($name, $formatting, $attributes) = @_;
+-
+-    unless (@{$self->{styletbl}}) {
+-        $self->add_raw ( $self->{styletbl}, '\stylesheet');
+-    }
+-
+-    $type = ${$attributes}{type} || "paragraph";
+-    my $code = $STYLETYPES{$type};
+-    unless (defined($code)) {
+-        carp "Don\'t know how to handle a \`$type\' style";
+-    }
+-
+-    my $style;
+-    if (${$attributes}{default}) {
+-        carp "Default style\'s type must be \`paragraph\'", if ($type ne "paragraph");       
+-        $code = "\\s0";
+-        $style = $code;
+-        $self->{$style} = $self->new_group();;
+-    } else {
+-        $code .= ++$self->{styleCnt};
+-        ($style = $code) =~ s/^\\\*//;
+-        $self->{$style} = $self->new_group( $code );
+-    }
+-
+-    $self->set_properties( \%PROPERTIES, $formatting, $self->{$style} );
+-
+-    carp "Warning: next attribute for style sheets is not used",
+-        if (defined(${$attributes}{next}));
+-
+-    my $sbasedon = ${$attributes}{basedon} || "none",
+-       $snext    = ${$attributes}{next}    || "self";
+-
+-    $sbasedon = decode_stylename($sbasedon, $style);
+-    $snext    = decode_stylename($snext, $style);
+-
+-    # --- Inherit stylesheet from "basedon"
+-    if ($sbasedon ne '\s222') {
+-         %{$self->{styles}->{$style}} = %{$self->{styles}->{$sbasedon}};
+-    } else {
+-        $self->{styles}->{$style} = {};
+-    }
+-
+-    foreach my $aux (keys %{$formatting}) {
+-        ${$self->{styles}->{$style}}{$aux} = ${$formatting}{$aux};
+-    }
+-
+-    $sbasedon =~ s/^\\[dc]?s//; $snext =~ s/^\\[dc]?s//;
+-
+-    push @{$self->{$style}}, ('\sbasedon'.$sbasedon), if (defined(${$attributes}{basedon}));
+-    push @{$self->{$style}}, ('\snext'.$snext), if (defined(${$attributes}{next}));
+-
+-    push @{$self->{$style}}, ('\shidden'), if (${$attributes}{hidden});
+-    push @{$self->{$style}}, ('\sautoupd'), if (${$attributes}{autoupdate});
+-
+-    if ($type eq "character") {
+-        if (${$attributes}{additive}) {
+-            push @{$self->{$style}}, '\additive';
+-        } else {
+-            ${$self->{styles}->{$style}}{plain} = 1;
+-        }
+-    } else {
+-         ${$self->{styles}->{$style}}{plain} = 1;
+-         ${$self->{styles}->{$style}}{pard}  = 1;
+-         if ($type eq "section") {
+-             ${$self->{styles}->{$style}}{secd}  = 1;
+-         }
+-    }
+-
+-    push @{$self->{$style}}, escape_simple($name).";";
+-
+-    if (${$attributes}{default}) {
+-        $self->splice_raw($self->{styletbl}, 1, 0, $self->{$style});
+-    } else {
+-        $self->add_raw($self->{styletbl}, $self->{$style});
+-    }
+-
+-    return $style;
+-}
+-
+-# --- These are the color names used in the HTML 4.0 spec. WordPad also uses these
+-#     names too. However, Microsoft's RTF 1.5 spec uses different color names.
+-
+-%COLORNAMES = (
+-    'black'	=> [0, 0, 0],
+-    'blue'	=> [0, 0, 255],
+-    'aqua'	=> [0, 255, 255],
+-    'lime'	=> [0, 255, 0],
+-    'fuscia'	=> [255, 0, 255],
+-    'red'	=> [255, 0, 0],
+-    'yellow'	=> [255, 255, 0],
+-    'white'	=> [255, 255, 255],
+-    'navy'	=> [0, 0, 128],
+-    'teal'	=> [0, 128, 128],
+-    'green'	=> [0, 128, 0],
+-    'purple'	=> [128, 0, 128],
+-    'maroon'	=> [128, 0, 0],
+-    'olive' 	=> [128, 128, 0],
+-    'gray'	=> [128, 128, 128],
+-    'silver'	=> [192, 192, 192],
+-);
+-
+-sub parse_value
+-{
+-    local ($_) = shift;
+-    $_ = $1 * 2.55, if (m/\-?(\d+(\.\d*)?)\s*\%$/);
+-    return POSIX::ceil($_);
+-}
+-
+-sub add_color
+-{
+-    my $self = shift;
+-    my $attributes = shift;
+-    my ($red, $grn, $blu);
+-
+-    if (defined(${$attributes}{name})) {
+-        my $name = ${$attributes}{name};
+-        ($red, $grn, $blu) = @{$COLORNAMES{$name}};
+-        carp "Unrecognized color name \`$name\'", 
+-          unless (defined($COLORNAMES{$name}));
+-    } else {
+-        $red = parse_value(${$attributes}{red});
+-        $grn = parse_value(${$attributes}{green});
+-        $blu = parse_value(${$attributes}{blue});
+-    }
+-
+-    if (${$attributes}{gray}) {
+-        ($red, $grn, $blu) = (255, 255, 255), unless ($red+$grn+$blu);
+-        
+-        $red = POSIX::ceil(parse_value(${$attributes}{gray}) / 255 * $red);
+-        $grn = POSIX::ceil(parse_value(${$attributes}{gray}) / 255 * $grn);
+-        $blu = POSIX::ceil(parse_value(${$attributes}{gray}) / 255 * $blu);
+-    }
+-
+-    unless ($self->{colorCnt}) {
+-        $self->add_raw ($self->{colortbl}, ('\colortbl', ';'));
+-    }
+-
+-    foreach ($red, $grn, $blu) {
+-        carp "Invalid color value: $_.", if ($_<0) or ($_>255);
+-    }
+-
+-    if (${$attributes}{default}) {
+-        carp "Default color will not used by most RTF readers";
+-        $self->splice_raw ($self->{colortbl}, 1, 1, ("\\red$red", "\\green$grn", "\\blue$blu;") );
+-        return 0;
+-    } else {
+-        $self->add_raw ($self->{colortbl}, ("\\red$red", "\\green$grn", "\\blue$blu;") );
+-        return ++$self->{colorCnt};
+-    }
+-}
+-
+-sub new_group {
+-    my $self = shift;
+-    my $group = [];
+-    push @{$group}, @_;
+-    return $group;
+-}
+-
+-sub add_group {
+-    my $self = shift;
+-    my $section = shift || $self->root();
+-    my $group = shift || $self->new_group();
+-    $self->add_raw ($section, $group);
+-    return $group;
+-}
+-
+-sub root {
+-    my $self = shift;
+-    return $self->{text};
+-}
+-
+-sub splice_raw # splice a raw value into a section
+-{
+-    my $self = shift;
+-    my $section = shift;
+-    my $position = shift;
+-    my $length = shift;
+-
+-    splice @{$section}, $position, $length, @_;
+-}
+-
+-sub add_raw # add a raw value to a section
+-{
+-    my $self = shift;
+-    my $section = shift;
+-
+-    push @{$section}, @_ ;
+-}
+-
+-
+-# --- Escape brackets, backslashes and 8-bit characters
+-sub escape_simple {
+-    local ($_) = shift;
+-    s/([\\\{\}])/\\$1/g;	
+-    s/([\x80-\xff])/sprintf("\\\'\%02x", ord($1))/eg;
+-    return $_;
+-}
+-
+-# --- Escapes special characters to common RTF controls
+-sub escape_text
+-{
+-    local ($_) = escape_simple(shift);
+-    s/\r/\\par/g;		# carriage returns = new paragraphs
+-    s/\n/\\line/g;		# escape newlines
+-    s/\t/\\tab/g;		# escape tabs
+-    return $_;
+-}
+-
+-sub split_text # splits special characters and regular text into list items
+-{
+-    my ($line) = shift;
+-
+-    $line =~ s/\r//g;		# remove carriage returns
+-    $line =~ s/\n\n/\r/g;		# change double-newlines to new carriage returns
+-
+-    my (@list) = ();
+-    local($_);
+-
+-    foreach (split /(?<=[\n\r\t\\\{\}])|(?=[\n\r\t\\\{\}])/, $line) {
+-        push @list, escape_text ($_);
+-    }
+-    return @list;
+-}
+-
+-sub add_text {
+-    my $self = shift;
+-    my $group = shift || $self->root();
+-    my ($arg, $rarg);
+-
+-    while ($arg = shift) {
+-        $rarg = ref($arg);
+-        if ($rarg eq HASH)
+-        {
+-            $self->set_properties (\%PROPERTIES, $arg, $group);
+-        }
+-        elsif ($rarg eq ARRAY)
+-        {
+-            my $subgroup = $self->add_group($group);
+-            $self->add_text ($subgroup, @{$arg} );
+-        }
+-        elsif ($rarg eq SCALAR)
+-        {
+-            $self->add_text (${$arg});
+-        }
+-        else
+-        {
+-            $self->add_raw ($group, split_text($arg));
+-        }
+-    }
+-}
+-
+-sub rtf
+-{
+-    my $self = shift;
+-
+-    unless ($self->{fontCnt}) {
+-        carp "No default font has been specified";
+-    }
+-
+-    return emit_group @{$self->{DOCUMENT}};
+-}
+-
+-1;
+-
+-__END__
+-
+-=head1 NAME
+-
+-RTF::Document - Perl extension for generating Rich Text (RTF) Files 
+-
+-=head1 DESCRIPTION
+-
+-RTF::Document is a module for generating Rich Text Format (RTF) documents
+-that can be used by most text converters and word processors.
+-
+-For a listing of properties, consult the %DOCINFO and %PROPERTIES hashes
+-in the source code.
+-
+-=head1 REQUIRED MODULES
+-
+-    Carp
+-    POSIX
+-    Convert::Units::Type 0.33
+-
+-=head1 EXAMPLE
+-
+-    use RTF::Document;
+-
+-    # Document properties
+-
+-    $rtf = new RTF::Document(
+-      {
+-        doc_page_width => '8.5in',
+-        doc_page_height => '11in'
+-      }
+-    );
+-
+-    # Font definitions
+-
+-    $fAvantGarde = $rtf->add_font ("AvantGarde", 
+-       { family=>swiss,
+-         default=>1
+-       } );
+-    $fCourier = $rtf->add_font ("Courier",
+-      { family=>monospace, pitch=>fixed, 
+-        alternates=>["Courier New", "American Typewriter"] 
+-      } );
+-
+-    # Color definitions
+-
+-    $cRed   = $rtf->add_color ( { red=>255 } );
+-    $cGreen = $rtf->add_color ( { green=>128 } );
+-    $cCustm = $rtf->add_color ( { red=>0x66, blue=>0x33, green=>0x33 } );
+-
+-    $cBlack = $rtf->add_color ( { name=>'black' } );
+-    $cWhite = $rtf->add_color ( { gray=>'100%' } );
+-
+-    $cNavy = $rtf->add_color ( { blue=>'100%', gray=>'50%' } );
+-
+-    # style definitions
+-
+-    $sNormal = $rtf->add_style( "Normal",
+-      { font=>$fAvantGarde, font_size=>'12pt',
+-        color_foreground=>$cBlack },
+-      { type=>paragraph, default=>1 }
+-    );
+-
+-    $sGreen = $rtf->add_style( "Green",
+-      { color_foreground=>$cGreen },
+-      { type=>character, additive=>1 }
+-    );
+-
+-    # Mix any combo of properties and text...
+-
+-    $rtf->add_text( $rtf->root(),
+-       "Default text\n\n",
+-
+-       { bold=>1, underline=>continuous },
+-       "Bold/Underlined Text\n\n",
+-
+-       { font_size=>'20pt', font=>$fCourier,
+-         color_foreground=>$cRed },
+-       "Bigger, Red and Monospaced.\n\n",
+-
+-       { style_default=>paragraph },
+-       { style_default=>character },
+-
+-       "This is ",
+-       [ { style=>$sGreen }, "green" ],
+-       " styled.\n\n"
+-
+-    );
+-
+-    open FILE, ">MyFile.rtf";
+-    binmode FILE;
+-    print FILE $rtf->rtf();
+-    close FILE;
+-
+-=head1 DOCUMENT STRUCTURE
+-
+-For purposes of using this module, a Rich Text (RTF) Document can be subdivided into
+-I<groups>. Groups can be considered containers for I<text> and I<controls> (controlling
+-document and text properties).
+-
+-For all intents and purposes, a group limits the scope of controls. So if we set
+-the "bold" character property within a group, the text will be bold only within
+-that group (until it is turned off within that group).
+-
+-When generating a RTF document using this module, we are only concerned with the
+-I<root> group (also called the "Document Area"). (The "Header" groups are taken
+-care of automatically by this module.)
+-
+-The Document Area is subdivided into I<sections>. Each section is subdivided into
+-I<paragraphs>.
+-
+-=head1 METHODS
+-
+-Some of the methods are documented below. (Methods not documented here may
+-be changed in future versions.)
+-
+-=head2 new
+-
+-    $rtf = new RTF::Document( \%DocumentProperties );
+-
+-Creates a new RTF document object.
+-
+-=head2 root
+-
+-    $gRoot = $rtf->root();
+-
+-Returns the "root" group in the RTF document.
+-
+-=head2 new_group
+-
+-    $gMyGroup = $rtf->new_group();
+-
+-Creates a new group (not inside of the RTF document).
+-
+-=head2 add_group
+-
+-    $gChildOfRoot = $rtf->add_group();
+-    $gChildOfChild = $rtf->add_group( $gChild );
+-
+-Adds a child group to the specfied group. If no group is specified, the "root"
+-group is assumed.
+-
+-    $rtf->add_group( $rtf->root(), $gMyGroup );
+-
+-Adds a group to the specified parent group (in this case, the root group).
+-
+-=head2 add_raw
+-
+-    $rtf->add_raw( $group, '\par', "Some Text" );
+-
+-Adds raw controls and text to the group. This method is intended for internal
+-use only.
+-
+-=head2 add_text
+-
+-    $rtf->add_text( $group, "Some text ", { bold=>1 }, "more text" );
+-
+-Adds text and controls to a group. Text is escaped.
+-
+-=head2 add_font
+-
+-=head2 add_color
+-
+-=head2 add_style
+-
+-=head1 PROPERTIES
+-
+-=head2 Document Properties
+-
+-=head2 Section Properties
+-
+-=head2 Paragraph Properties
+-
+-=head2 Character Properties
+-
+-=head1 KNOWN ISSUES
+-
+-This module should be considered in the "alpha" stage. Use at your own risk.
+-
+-There are no default document or style properties produced by this module,
+-with the exception of the character set. If you want to make sure that a
+-I<specific> font, color, or style is used, you must specify it. Otherwise
+-you rely on the assumptions of whatever RTF reader someone is using.
+-
+-This module does not insert newlines anywhere in the text, even though some
+-RTF writers break lines before they exceed 225 characters.  This may or may
+-not be an issue with some reader software.
+-
+-Unknown font or style properties will generally be ignored without warning.
+-
+-This module supports some newer RTF controls (used in Word 95/Word 97) that
+-may are not understood by older RTF readers.
+-
+-Once a Font, Color or Style is added, it cannot be changed. No checking
+-for redundant entries is done.
+-
+-Generally, it is not possible to reference a not-yet-created Style with the
+-next or basedon attributes. However, you can use the constances "last",
+-"self" or "next" to reference the last style added, the current style
+-being added, or the next style that will be added, respectively.
+-
+-Specifying properties in a particular order within a group does not
+-guarantee that they will be emitted in that order. If order matters,
+-specify them separetly. For instance,
+-
+-    $rtf->add_text($rtf->root, { style_default=>character, bold=>1 } );
+-
+-should be (if you want to ensure character styles are reset before setting
+-bold text):
+-
+-    $rtf->add_text($rtf->root, { style_default=>character }, { bold=>1 } );
+-
+-Also note that duplicate properties within the same group won't work. i.e.,
+-If you want to set "style_default" for both paragraphs and characters, you
+-must do so in separate groups.
+-
+-This isn't so much as a bug as the way Perl handles hashes.
+-
+-=head2 Unimplemented Features
+-
+-A rather large number of features and control words are not handled in this
+-version. Among the major features:
+-
+-=over
+-
+-=item Annotations and Comments
+-
+-=item Bookmarks
+-
+-=item Bullets and Paragraph Numbering
+-
+-Some support has been added. The backwards-compatability controls for numbered
+-paragraphs used by older readers has not been added because it is not properly
+-handled by newer readers.
+-
+-=item Character Sets and Internationalization
+-
+-Non-"ANSI" character sets (i.e., Macintosh) and Unicode character
+-sets are not supported (at least not intentionally). There is no
+-support for Asian character sets in this version of the module.
+-
+-Unicode character escapes are not implemented.
+-
+-Language codes (defining a default language, or a language for a
+-group of characters) are not implemented.
+-
+-Bi-directional and text-flow controls are not implemented.
+-
+-=item Embedded Images and OLE Objects
+-
+-=item File Tables
+-
+-=item Footnotes and Endnotes
+-
+-=item Forms
+-
+-=item Headers and Footers
+-
+-=item Hyphenation Control
+-
+-Some minimal controls have been added.
+-
+-=item Lists and List Tables
+-
+-Not implemented: List Tables are really a kind of style sheet for lists.
+-Priority will be given to support generic bullets and paragraph numbering.
+-
+-=item Page Numbering
+-
+-Minimal definition, untested.
+-
+-=item Printer Bin Controls
+-
+-=item Revision Tables
+-
+-=item Special Characters and Document Variables
+-
+-Most special characters not not implemented, with the exception of tabs. Double
+-newline characters are converted to a new paragraph control, and single newlines
+-are converted to a new line control.
+-
+-=item Tabs
+-
+-=item Tables and Frames
+-
+-=back
+-
+-=head1 SEE ALSO
+-
+-Microsoft Technical Support and Application Note, "Rich Text Format (RTF)
+-Specification and Sample Reader Program", Version 1.5.
+-
+-I<Convert::Units::Type>.
+-
+-=head1 AUTHOR
+-
+-Robert Rothenberg <wlkng...@unix.asb.com>
+-
+-=head1 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.
+-
+-=cut
+-
++package RTF::Document;
++require 5.005;
++require Exporter;
++
++use vars qw(
++    $VERSION
++    %DOCINFO %PROPERTIES
++    %FONTCLASSES %FONTPITCH %COLORNAMES %STYLETYPES %NUMSTYLES
++);
++$VERSION = "0.64";
++
++@ISA = qw(Exporter);
++@EXPORT = qw();
++@EXPORT_OK = qw();
++
++use Carp;
++use POSIX qw(floor ceil);
++use Convert::Units::Type 0.33;
++
++%NUMSTYLES = (
++    '1' => '\pndec',
++    'a' => '\pnlcltr',
++    'i' => '\pnlcrm',
++    'A' => '\pnucltr',
++    'I' => '\pnucrm',
++    '1st' => '\pnord'
++);
++
++sub _prop_list
++{
++    my ($self, $code, $properties) = @_;
++    my ($result, $level, $style);
++
++    if ($properties eq "off") {
++        return '\pard';
++    }
++
++    $result = $self->new_group( '\*', '\pn' );
++
++    ${$properties}{level} = ${$properties}{style}, if (${$properties}{style} eq "bullet");
++
++    if (${$properties}{level}) {
++        $level = ${$properties}{level};
++        $level = "blt", if ($level eq "bullet");
++        if ((($level<1) or ($level>11)) and ($level ne "blt"))
++        {
++            carp "List level \`$level\' is out of range";
++            $level = 'body';
++        }
++    } else {
++        $level = 'body';
++    }
++
++    $self->add_raw ($result, '\pnlvl'.$level);
++
++    if ($level eq "body")  {
++        $style = $NUMSTYLES{${$properties}{style}} || '\pndec';
++        $self->add_raw ($result, $style);
++    }
++
++    if (defined(${$properties}{font}))
++    {
++       $self->add_raw ($result, '\pnf'.${$properties}{font});
++    }
++
++    if (defined(${$properties}{color}))
++    {
++       $self->add_raw ($result, '\pncf'.${$properties}{color});
++    }
++
++    if (defined(${$properties}{before}))
++    {
++       my $group = $self->add_group($result);
++       $self->add_raw ($group, '\pntxtb '.escape_simple(${$properties}{before}) );
++    }
++
++    if (defined(${$properties}{after}))
++    {
++       my $group = $self->add_group($result);
++       $self->add_raw ($group, '\pntxta '.escape_simple(${$properties}{after}) );
++    }
++
++    if (${$properties}{across})
++    {
++       $self->add_raw ($result, '\pnacross');
++    }
++
++    if (defined(${$properties}{indent}))
++    {
++       $self->add_raw ($result, '\pnindent'.POSIX::floor(
++         Convert::Units::Type::convert(${$properties}{indent}, "twips")
++       ));
++    }
++
++    if (defined(${$properties}{space}))
++    {
++       $self->add_raw ($result, '\pnsp'.POSIX::floor(
++         Convert::Units::Type::convert(${$properties}{space}, "twips")
++       ));
++    }
++
++    if (${$properties}{hang})
++    {
++       $self->add_raw ($result, '\pnhang');
++    }
++
++    if (defined(${$properties}{start}))
++    {
++       $self->add_raw ($result, '\pnstart'.${$properties}{start});
++    }
++
++
++    return ($result);
++}
++
++# $arg is a key to RTF control in hash value
++sub _prop_decode
++{
++    my ($self, $hash, $arg) = @_;
++    my $result = ${$hash}{$arg};
++
++    unless (defined($result)) {
++        carp "Don\'t know how to handle value \`$arg\'";
++    }
++
++    return ("\\".$result);
++}
++
++sub _prop_style {
++    my ($self, $code, $arg) = @_;
++    $code = decode_stylename($arg, '\s222');
++    my $formatting, $style_properties;
++
++    if (defined($code)) {
++        $formatting = $self->new_group();
++        %{$style_properties} = %{$self->{styles}->{$code}};
++
++        if (${$style_properties}{secd}) {
++            $self->add_raw($formatting, '\secd');
++            delete ${$style_properties}{secd};
++        }
++        if (${$style_properties}{pard}) {
++            $self->add_raw($formatting, '\pard');
++            delete ${$style_properties}{pard};
++        }
++        if (${$style_properties}{plain}) {
++            $self->add_raw($formatting, '\plain');
++            delete ${$style_properties}{plain};
++        }
++
++        $self->set_properties( \%PROPERTIES, $style_properties, $formatting);
++        unless (@{$formatting}) {
++            carp "Style \`$arg\' is not defined";
++            $code = decode_stylename("none");
++        }
++    }
++    return ($code, @{$formatting} );
++}
++
++# $arg is a unit of type (points, picas, inches) converted to twips
++sub _prop_twips {
++    my ($self, $code, $arg) = @_;
++    return ("\\".$code.POSIX::floor(Convert::Units::Type::convert($arg, "twips")));
++}
++
++# $arg is a unit of type (points, picas, inches) converted to half-points
++sub _prop_halfpts {
++    my ($self, $code, $arg) = @_;
++    return ("\\".$code.POSIX::floor(Convert::Units::Type::convert($arg, "half-points")));
++}
++
++# $arg is a string (which may need to be escaped)
++sub _prop_pcdata {
++    my ($self, $code, $arg) = @_;
++    $arg =~ s/([\\\{\}])/\\$1/g;
++    return ("\\".$code, escape_simple($arg));
++}
++
++# $arg is a raw value
++sub _prop_raw {
++    my ($self, $code, $arg) = @_;
++    return ("\\".$code.$arg);
++}
++
++# $arg is a an on/off indicator (0 = off, NZ = on)
++sub _prop_onoff {
++    my ($self, $code, $arg) = @_;
++    if ($arg)
++    {
++        return ("\\".$code);
++    }
++    else
++    {
++        return ("\\".$code."0");
++    }
++}
++
++# $arg is a an emit/don't emit indicator (0 = don't emit control, NZ = emit)
++sub _prop_on {
++    my ($self, $code, $arg) = @_;
++    if ($arg)
++    {
++        return ("\\".$code);
++    }
++    else
++    {
++        return undef;
++    }
++}
++
++# Synopsis of %DOCINFO and %PROPERTIES
++#   property => [ where, control, group, function ]
++#     property = name of the property
++#     where    = what section of the document this control is usually applied to
++#     control	 = the control word used (if a hash, how to decode various controls)
++#     group    = if non-zero, emit this as part of a group
++#     function = what function to use to process this property
++# Most properties follow the following naming scheme:
++#  doc = document-wide properties (should be set only once)
++#  sec = section properties
++#  col = column properties (within a section)
++#  par = paragraph properties
++
++%DOCINFO = (
++    # --- Document summary information
++    'doc_title'		=> [ 'info',  'title', 	1, \&_prop_pcdata ],
++    'doc_author'		=> [ 'info',  'author',	1, \&_prop_pcdata ],
++    'doc_subject'		=> [ 'info',  'subject',	1, \&_prop_pcdata ],
++    'doc_manager'		=> [ 'info',  'manager',	1, \&_prop_pcdata ],
++    'doc_company'		=> [ 'info',  'company',	1, \&_prop_pcdata ],
++    'doc_operator'		=> [ 'info',  'operator',	1, \&_prop_pcdata ],
++    'doc_category'		=> [ 'info',  'category',	1, \&_prop_pcdata ],
++    'doc_keywords'		=> [ 'info',  'keywords',	1, \&_prop_pcdata ],
++    'doc_summary'		=> [ 'info',  'doccomm',	1, \&_prop_pcdata ],
++    'doc_comment'		=> [ 'text',  '*\comment',	1, \&_prop_pcdata ],
++    'doc_base_href'		=> [ 'info',  'hlinkbase', 	1, \&_prop_pcdata ],
++    'doc_version'		=> [ 'info',  'version',	0, \&_prop_raw  ],
++    'doc_time_created'	=> [ 'creatim' ],
++
++    'doc_from_text'		=> [ 'text',  'fromtext',    0, \&_prop_on ],
++    'doc_make_backup'	=> [ 'text',  'makebackup',  0, \&_prop_on ],
++    'doc_rtf_def'		=> [ 'text',  'defformat',   0, \&_prop_on ],
++
++    # --- Page sizes, margins, etc.
++    doc_page_width	=> [ text,  paperw,	0, \&_prop_twips ],
++    doc_page_height	=> [ text,  paperh,	0, \&_prop_twips ],
++    doc_landscape	=> [ text,  landscape,	0, \&_prop_on ],
++    doc_facing	=> [ text,  facingp,	0, \&_prop_on ],
++    doc_margin_left	=> [ text,  margl,		0,  \&_prop_twips ],
++    doc_margin_right	=> [ text,  margr,		0, \&_prop_twips ],
++    doc_margin_top	=> [ text,  margt,		0, \&_prop_twips ],
++    doc_margin_bottom => [ text,  margb, 	0, \&_prop_twips ],
++    doc_margin_mirror=> [ text,  margmirror, 	0, \&_prop_on ],
++    doc_gutter	=> [ text,  gutter, 	0, \&_prop_twips ],
++
++    # --- Hyphenation
++    doc_hyphen_auto	=> [ 'text', 'hyphauto', 0,  \&_prop_onoff ],
++    doc_hyphen_caps	=> [ 'text', 'hyphcaps', 0,  \&_prop_onoff ],
++    doc_hyphen_lines	=> [ 'text', 'hyphconsec', 0,  \&_prop_onoff ],
++    doc_hyphen_zone	=> [ 'text', 'hyphhotz', 0,  \&_prop_twips ],
++
++    # --- Views
++    doc_view_scale	=> [ text,  viewscale,   0, \&_prop_raw  ],
++    doc_view_zoom	=> [ text, { none=>'viewzk0', 'full-page'=>'viewzk1',
++      'best-fit'=>'viewzk1' },  0, \&_prop_decode ],
++    doc_view_caption	=> [ text, windowcaption, 1, , \&_prop_pcdata ],
++    'doc_view_mode'	=> [ 'text', { 'none'=>'viewkind0', 'layout'=>'viewkind1',
++      'outline'=>'viewkind2', 'master'=>'viewkind3',
++
++
++
++
++      'normal'=>'viewkind4', 'online'=>'viewkind5'}, 0, \&_prop_decode ],
++
++    # --- Character set
++    'doc_charset'		=> [ 'charset' ],
++
++    # --- Widow/orphan controls
++    doc_widow_cntrl	=> [ text,  widowctrl,   0, \&_prop_on ],
++
++    # --- Tabs
++    tabs_default	=> [ 'text',  'deftab', 	0, \&_prop_twips ],
++
++);
++
++%PROPERTIES = (
++
++    # --- New section, paragraph, line
++    'sec'		=> [ 'text', 'sect', 	0, \&_prop_on ],
++    'par'		=> [ 'text', 'par', 		0, \&_prop_on ],
++    'line'		=> [ 'text', 'line', 	0, \&_prop_on ],
++    'line_soft'	=> [ 'text', 'softline', 	0, \&_prop_on ],
++
++    # --- Sections....
++    'sec_brk'		=> [ 'text', { 'none'=>'sbknone', 'column'=>'sbkcol',
++      'page'=>'sbkpage', 'even'=>'sbkeven', 'odd'=>'sbkodd'}, 0, \&_prop_decode ],
++
++    # --- Columns
++    col		=> [ text,  'colulmn',  	0, \&_prop_on ],
++    col_soft		=> [ text,  'softcol',  	0, \&_prop_on ],
++    col_num		=> [ text,  'cols',  	0, \&_prop_raw ],
++    col_space		=> [ text,  'colsx', 	0, \&_prop_twips ],
++    col_select	=> [ text,  'colno', 	0, \&_prop_raw ],
++    col_padding_right => [ text, 'colsr', 	0, \&_prop_twips ],
++    col_width 	=> [ text,  'colw',		0, \&_prop_twips ],
++    col_line		=> [ text,  'linebetcol',	0, \&_prop_on ],
++
++    'page_brk'	=> [ 'text', 'page', 	0, \&_prop_on ],
++    'page_softbrk'	=> [ 'text', 'softpage',	0, \&_prop_on ],
++
++    # --- Forms....
++    'sec_unlock'	=> [ 'text', 'sectunlocked', 	0, \&_prop_on ],
++
++    # --- Footsnotes, endnotes stuff
++    'sec_endnotes_here' => [ 'text', 'endnhere',	0, \&_prop_on ],
++
++    # --- Alignment
++    'par_align'	=> [ 'text', { left=>'ql', right=>'qr', center=>'qc', justify=>'qj' },  0, \&_prop_decode ],
++    'sec_vert_align'	=> [ 'text', { top=>vertalt, bottom=>vertalb, center=>vertalc },  0, \&_prop_decode ],
++
++    # --- Indentation
++    'par_indent_first'	=> [ 'text', 'fi', 	0, \&_prop_twips ],
++    'par_indent_left'	=> [ 'text', 'li', 	0, \&_prop_twips ],
++    'par_indent_right'	=> [ 'text', 'ri', 	0, \&_prop_twips ],
++    'par_outline_level'	=> [ 'text', 'outlinelevel', 0, \&_prop_raw ],
++
++    'par_number_text'	=> [ 'text', 'pntext', 1, \&_prop_pcdata ],
++    'par_number'		=> [ 'text', 'pn', 0, \&_prop_list ],
++
++    # --- Style
++    'style'		=> [ 'text', 's', 		0, \&_prop_style ],
++    'style_default'	=> [ 'text', { 'character'=>'plain', 'paragraph'=>'pard',
++        'section'=>'secd', 'row'=>'trowd', 'cell'=>'tcelld' },  0, \&_prop_decode ],
++
++    # --- Paragraph spacing
++    'par_space_before'	=> [ 'text', 'sb',	0,  \&_prop_twips ],
++    'par_space_after'	=> [ 'text', 'sa',	0,  \&_prop_twips  ],
++    'par_space_lines'	=> [ 'text', 'sl',	0,  \&_prop_raw  ],
++    'par_space_lines_mult'	=> [ 'text', 'slmult', 0,  \&_prop_raw  ],
++
++    # --- Character formatting
++    'bold'		=> [ 'text',  'b',		0,  \&_prop_onoff ],
++    'italic'		=> [ 'text',  'i',		0,  \&_prop_onoff ],
++    'caps'		=> [ 'text',  'caps',	0,  \&_prop_onoff ],
++    'caps_small'	=> [ 'text',  'scaps',	0,  \&_prop_onoff ],
++    'underline'	=> [ 'text', { 'off'=>'ul0', 'continuous'=>'ul', 'dotted'=>'uld',
++        'dash'=>'uldash', 'dot-dash'=>'uldashd', 'dot-dot-dash'=>'uldashdd',
++        'double'=>'ulb', 'none'=>'ulnone', 'thick'=>'ulth', 'word'=>'ulw',
++        'wave'=>'ulwave' },  0, \&_prop_decode ],
++    'hidden'			=> [ 'text', 'v',		0,  \&_prop_onoff ],
++
++    # --- Colors
++    'color_foreground' 	=> [ 'text', 'cf',		0, \&_prop_raw ],
++    'color_background' 	=> [ 'text', 'cb',		0, \&_prop_raw ],
++    'highlight'		=> [ 'text', 'highlight',	0, \&_prop_raw ],
++
++    # --- Fonts
++    'font'			=> [ 'text', 'f', 		0, \&_prop_raw ],
++    'font_size'		=> [ 'text', 'fs',		0, \&_prop_halfpts ],
++    'font_scale'		=> [ 'text', 'charscalex', 	0,  \&_prop_raw  ],
++
++    # --- Page sizes, margins, etc.
++    'sec_page_width'		=> [ 'text', 'pgwsxn',	0, \&_prop_twips ],
++    'sec_page_height' 	=> [ 'text', 'pghsxn',	0, \&_prop_twips ],
++    'sec_landscape'		=> [ 'text', 'lndscpsxn',	0, \&_prop_on ],
++    'sec_margin_left' 	=> [ 'text', 'marglsxn',	0, \&_prop_twips ],
++    'sec_margin_right' 	=> [ 'text', 'margrsxn',	0, \&_prop_twips ],
++    'sec_margin_top'	 	=> [ 'text', 'margtsxn',	0, \&_prop_twips ],
++    'sec_margin_bottom' 	=> [ 'text', 'margbsxn', 	0, \&_prop_twips ],
++    'sec_margin_mirror' 	=> [ 'text', 'margmirsxn',	0, \&_prop_on ],
++    'sec_gutter'		=> [ 'text', 'guttersxn', 	0, \&_prop_twips ],
++
++    'sec_title_pg' 		=> [ 'text', 'titlepg', 	0, \&_prop_on ],
++    'sec_header_margin' 	=> [ 'text', 'headery', 	0, \&_prop_twips ],
++    'sec_footer_margin' 	=> [ 'text', 'footery', 	0, \&_prop_twips ],
++
++    # --- Hyphenation
++    'par_hyphen'		=> [ 'text', 'hyphpar', 	0,  \&_prop_onoff ],
++
++    # --- Widow/orphan controls
++    'par_widow_cntrl' 	=> [ text, { 0=>nowidctlpar, 1=>widctlpar }, 0, \&_prop_decode ],
++    'par_intact'		=> [ 'text', 'keep',  	0, \&_prop_on ],
++    'par_keep_next'		=> [ 'text', 'keepn',	0, \&_prop_on ],
++
++    'par_pgbrk_before' 	=> [ 'text', 'pagebb',	0, \&_prop_on ],
++
++    # --- Page numbering
++    'pg_num_start' 		=> [ 'text', 'pgnstart',	0, \&_prop_raw ],
++    'pg_num_cont'		=> [ 'text', 'pgncont',	0, \&_prop_on ],
++    'pg_num_restart' 	=> [ 'text', 'pgnrestart',	0, \&_prop_on ],
++
++    'sec_title_pg' 		=> [ 'text', 'titlepg', 	0, \&_prop_on ]
++);
++
++sub set_properties
++{
++    my $self = shift;
++
++    my $table = shift,
++       $settings = shift,
++       $destination = shift;
++    my ($property, $value, $where, $what, $arg, $default);
++
++    local ($_);
++
++    foreach $property (keys %{$settings}) {   
++        if (defined(${$table}{$property}))
++        {
++            ($where, $what, $group, $default, $arg) = @{${$table}{$property}};
++
++            if (defined($destination))
++            {
++                carp "\`$property\' is not a section, paragraph or character property",
++                    if ($where ne "text");
++                $where = $destination;
++            } else {
++                $where = $self->{$where}, if (defined($what));
++            }
++
++            if (defined($what))
++            {
++                $value = ${$settings}{$property};
++                my @controls = $self->$default($what, $value, $arg);
++
++                if (@controls)
++                {
++                    if ($group) {
++                        my $subgroup = $self->add_group($where);
++                        $self->add_raw ($subroup, @controls );
++                    } else {
++                        $self->add_raw ($where, @controls );
++                    }
++                }                
++            } else {
++                $self->{$where} = ${$settings}{$property};
++            }
++
++        } else {
++            carp "Don\'t know how to handle property: \`$property\'";
++        }
++    }
++}
++
++sub initialize
++{
++    my $self = shift;
++    $self->{charset} 	= "ansi";	# Character Set
++
++    # --- Document Header
++    $self->{DOCUMENT}	= $self->new_group( '\rtf', $self->{charset} );
++
++    $self->{fonttbl}		= $self->add_group($self->{DOCUMENT});
++    $self->{fontCnt}		= 0;
++
++    $self->{colortbl}	= $self->add_group($self->{DOCUMENT});
++    $self->{colorCnt}	= 0;	# count of colors in table
++
++    $self->{styletbl} 	= $self->add_group($self->{DOCUMENT});
++    $self->{styleCnt}	= 0;	# count of styles defined
++
++    $self->{text} 		= $self->add_group($self->{DOCUMENT});
++
++    $self->{info} 		= $self->add_group();
++    $self->add_raw		( $self->{info}, '\info' );
++    $self->{creatim} 	= time();
++}
++
++sub import {
++    my $self = shift;
++    $self->set_properties (\%DOCINFO, @_);
++
++    $self->splice_raw ($self->{DOCUMENT}, 1, 1, "\\".$self->{charset});
++
++    # --- Insert creation time in Information Group
++    if ($self->{creatim})
++    {
++        my ($ss, $mn, $hr, $dd, $mm, $yy) = localtime($self->{creatim});
++        $yy+=1900; $mm++;
++
++        my $creatim = $self->add_group($self->{info});
++
++        $self->add_raw( $creatim,  '\creatim',
++            "\\yr$yy", "\\mo$mm", "\\dy$dd", "\\hr$hr", "\\min$mn", "\\sec$ss"
++        );
++        $self->{creatim} = 0;
++    };
++}
++
++sub new
++{
++    my $this = shift;
++    my $class = ref($this) || $this;
++    my $self = {};
++    bless $self, $class;
++    $self->initialize();
++    $self->import(@_);
++    return $self;
++}
++
++sub emit_group {
++    local ($el, $data);
++
++    unless (@_) {
++        return undef;
++    }
++
++    $data = "\{";
++
++    foreach $el (@_)
++    {
++        if (ref($el) eq ARRAY) {
++            $data .= emit_group(@$el);
++        } else {
++            if (($el !~ m/^[\\\;\{\}]/) and (substr($data, length($data)-1) !~ m/[\}\{\s]/)) {
++                $data .= " ";
++            }
++            $data .= $el;
++        }
++    }
++    $data .= "\}";
++    return $data;
++
++}
++
++
++%FONTCLASSES = (
++    'swiss'	=> 'swiss',
++    'sans-serif' => 'swiss',
++    'roman'	=> 'roman',
++    'serif'	=> 'roman',
++    'modern'	=> 'modern',
++    'monospace' => 'modern',
++    'script'	=> 'script',
++    'decor'	=> 'decor',
++    'fantasy'	=> 'decor',
++    'tech'	=> 'tech',
++    'symbol'	=> 'tech',
++    'bidi'	=> 'bidi'
++);
++%FONTPITCH = (
++    'default' => 0,
++    'fixed'  	=> 1,
++    'variable' => 2
++);
++sub add_font
++{
++    local ($_);
++    my $self = shift;
++
++    my $name = shift,
++       $attributes = shift;
++
++    my $class = $FONTCLASSES{${$attributes}{family}};
++
++    unless (defined($class)) {
++        $class = "nil";
++        carp "Unknown font family \`${$attributes}{family}\'";
++    }
++
++    unless ($self->{fontCnt}) {
++        $self->add_raw ($self->{fonttbl}, '\fonttbl');
++        $self->splice_raw ($self->{DOCUMENT}, 2, 0, "\\deff".$self->{fontCnt});
++    }
++
++    my $fattr = $self->add_group($self->{fonttbl});
++
++    $self->add_raw ($fattr, ('\f'.$self->{fontCnt}, '\f'.$class) );
++
++    if (defined(my $pitch = ${$attributes}{pitch}))
++    {
++        $self->add_raw ($fattr, '\fprq'. ($FONTPITCH{ $pitch }
++            or carp "Don\'t know how to handle \`pitch => $pitch\'" )
++        );
++    }
++
++    if (defined(my $actual = ${$attributes}{name})) # non-tagged name (is this correct?)
++    {
++        $self->add_raw ($fattr, ['\*\fname '.escape_simple($actual) ] );
++    }
++
++    $self->add_raw ($fattr, escape_simple($name) );
++
++    my @alternates = @{${$attributes}{alternates}};
++    if (@alternates) {
++        while ($_ = shift @alternates) {
++            $self->add_raw ($fattr, [ '\*\falt '.escape_simple($_) ] );
++        }
++    }
++
++    $self->add_raw ($fattr, ';' );
++
++    if (${$attributes}{default}) {
++        carp "Default font redefined",
++            if (@{$self->{DOCUMENT}}[2] ne "\\deff0");
++            @{$self->{DOCUMENT}}[2] = "\\deff".$self->{fontCnt};
++    }
++
++    return $self->{fontCnt}++;
++}
++
++sub decode_stylename
++{
++    my $name = shift;
++    my $current = shift || '\s0';
++
++    $current =~ m/^\\[cd]?s(\d+)/;
++    my ($next, $last) = ($1+1, $1-1);
++    $last = 222, if ($last<0);
++   
++    return '\s222', if ($name eq "none");
++    return '\s0', if ($name eq "default");
++    return $current, if ($name eq "self");
++    return '\s'.$next, if ($name eq "next");
++    return '\s'.$last, if ($name eq "last");
++    return $name;
++}
++
++%STYLETYPES = (
++    'character' => '\*\cs',
++    'paragraph' => '\s',
++    'section' => '\ds'
++);
++
++sub add_style
++{
++    my $self = shift;
++    my ($name, $formatting, $attributes) = @_;
++
++    unless (@{$self->{styletbl}}) {
++        $self->add_raw ( $self->{styletbl}, '\stylesheet');
++    }
++
++    $type = ${$attributes}{type} || "paragraph";
++    my $code = $STYLETYPES{$type};
++    unless (defined($code)) {
++        carp "Don\'t know how to handle a \`$type\' style";
++    }
++
++    my $style;
++    if (${$attributes}{default}) {
++        carp "Default style\'s type must be \`paragraph\'", if ($type ne "paragraph");       
++        $code = "\\s0";
++        $style = $code;
++        $self->{$style} = $self->new_group();;
++    } else {
++        $code .= ++$self->{styleCnt};
++        ($style = $code) =~ s/^\\\*//;
++        $self->{$style} = $self->new_group( $code );
++    }
++
++    $self->set_properties( \%PROPERTIES, $formatting, $self->{$style} );
++
++    carp "Warning: next attribute for style sheets is not used",
++        if (defined(${$attributes}{next}));
++
++    my $sbasedon = ${$attributes}{basedon} || "none",
++       $snext    = ${$attributes}{next}    || "self";
++
++    $sbasedon = decode_stylename($sbasedon, $style);
++    $snext    = decode_stylename($snext, $style);
++
++    # --- Inherit stylesheet from "basedon"
++    if ($sbasedon ne '\s222') {
++         %{$self->{styles}->{$style}} = %{$self->{styles}->{$sbasedon}};
++    } else {
++        $self->{styles}->{$style} = {};
++    }
++
++    foreach my $aux (keys %{$formatting}) {
++        ${$self->{styles}->{$style}}{$aux} = ${$formatting}{$aux};
++    }
++
++    $sbasedon =~ s/^\\[dc]?s//; $snext =~ s/^\\[dc]?s//;
++
++    push @{$self->{$style}}, ('\sbasedon'.$sbasedon), if (defined(${$attributes}{basedon}));
++    push @{$self->{$style}}, ('\snext'.$snext), if (defined(${$attributes}{next}));
++
++    push @{$self->{$style}}, ('\shidden'), if (${$attributes}{hidden});
++    push @{$self->{$style}}, ('\sautoupd'), if (${$attributes}{autoupdate});
++
++    if ($type eq "character") {
++        if (${$attributes}{additive}) {
++            push @{$self->{$style}}, '\additive';
++        } else {
++            ${$self->{styles}->{$style}}{plain} = 1;
++        }
++    } else {
++         ${$self->{styles}->{$style}}{plain} = 1;
++         ${$self->{styles}->{$style}}{pard}  = 1;
++         if ($type eq "section") {
++             ${$self->{styles}->{$style}}{secd}  = 1;
++         }
++    }
++
++    push @{$self->{$style}}, escape_simple($name).";";
++
++    if (${$attributes}{default}) {
++        $self->splice_raw($self->{styletbl}, 1, 0, $self->{$style});
++    } else {
++        $self->add_raw($self->{styletbl}, $self->{$style});
++    }
++
++    return $style;
++}
++
++# --- These are the color names used in the HTML 4.0 spec. WordPad also uses these
++#     names too. However, Microsoft's RTF 1.5 spec uses different color names.
++
++%COLORNAMES = (
++    'black'	=> [0, 0, 0],
++    'blue'	=> [0, 0, 255],
++    'aqua'	=> [0, 255, 255],
++    'lime'	=> [0, 255, 0],
++    'fuscia'	=> [255, 0, 255],
++    'red'	=> [255, 0, 0],
++    'yellow'	=> [255, 255, 0],
++    'white'	=> [255, 255, 255],
++    'navy'	=> [0, 0, 128],
++    'teal'	=> [0, 128, 128],
++    'green'	=> [0, 128, 0],
++    'purple'	=> [128, 0, 128],
++    'maroon'	=> [128, 0, 0],
++    'olive' 	=> [128, 128, 0],
++    'gray'	=> [128, 128, 128],
++    'silver'	=> [192, 192, 192],
++);
++
++sub parse_value
++{
++    local ($_) = shift;
++    $_ = $1 * 2.55, if (m/\-?(\d+(\.\d*)?)\s*\%$/);
++    return POSIX::ceil($_);
++}
++
++sub add_color
++{
++    my $self = shift;
++    my $attributes = shift;
++    my ($red, $grn, $blu);
++
++    if (defined(${$attributes}{name})) {
++        my $name = ${$attributes}{name};
++        ($red, $grn, $blu) = @{$COLORNAMES{$name}};
++        carp "Unrecognized color name \`$name\'", 
++          unless (defined($COLORNAMES{$name}));
++    } else {
++        $red = parse_value(${$attributes}{red});
++        $grn = parse_value(${$attributes}{green});
++        $blu = parse_value(${$attributes}{blue});
++    }
++
++    if (${$attributes}{gray}) {
++        ($red, $grn, $blu) = (255, 255, 255), unless ($red+$grn+$blu);
++        
++        $red = POSIX::ceil(parse_value(${$attributes}{gray}) / 255 * $red);
++        $grn = POSIX::ceil(parse_value(${$attributes}{gray}) / 255 * $grn);
++        $blu = POSIX::ceil(parse_value(${$attributes}{gray}) / 255 * $blu);
++    }
++
++    unless ($self->{colorCnt}) {
++        $self->add_raw ($self->{colortbl}, ('\colortbl', ';'));
++    }
++
++    foreach ($red, $grn, $blu) {
++        carp "Invalid color value: $_.", if ($_<0) or ($_>255);
++    }
++
++    if (${$attributes}{default}) {
++        carp "Default color will not used by most RTF readers";
++        $self->splice_raw ($self->{colortbl}, 1, 1, ("\\red$red", "\\green$grn", "\\blue$blu;") );
++        return 0;
++    } else {
++        $self->add_raw ($self->{colortbl}, ("\\red$red", "\\green$grn", "\\blue$blu;") );
++        return ++$self->{colorCnt};
++    }
++}
++
++sub new_group {
++    my $self = shift;
++    my $group = [];
++    push @{$group}, @_;
++    return $group;
++}
++
++sub add_group {
++    my $self = shift;
++    my $section = shift || $self->root();
++    my $group = shift || $self->new_group();
++    $self->add_raw ($section, $group);
++    return $group;
++}
++
++sub root {
++    my $self = shift;
++    return $self->{text};
++}
++
++sub splice_raw # splice a raw value into a section
++{
++    my $self = shift;
++    my $section = shift;
++    my $position = shift;
++    my $length = shift;
++
++    splice @{$section}, $position, $length, @_;
++}
++
++sub add_raw # add a raw value to a section
++{
++    my $self = shift;
++    my $section = shift;
++
++    push @{$section}, @_ ;
++}
++
++
++# --- Escape brackets, backslashes and 8-bit characters
++sub escape_simple {
++    local ($_) = shift;
++    s/([\\\{\}])/\\$1/g;	
++    s/([\x80-\xff])/sprintf("\\\'\%02x", ord($1))/eg;
++    return $_;
++}
++
++# --- Escapes special characters to common RTF controls
++sub escape_text
++{
++    local ($_) = escape_simple(shift);
++    s/\r/\\par/g;		# carriage returns = new paragraphs
++    s/\n/\\line/g;		# escape newlines
++    s/\t/\\tab/g;		# escape tabs
++    return $_;
++}
++
++sub split_text # splits special characters and regular text into list items
++{
++    my ($line) = shift;
++
++    $line =~ s/\r//g;		# remove carriage returns
++    $line =~ s/\n\n/\r/g;		# change double-newlines to new carriage returns
++
++    my (@list) = ();
++    local($_);
++
++    foreach (split /(?<=[\n\r\t\\\{\}])|(?=[\n\r\t\\\{\}])/, $line) {
++        push @list, escape_text ($_);
++    }
++    return @list;
++}
++
++sub add_text {
++    my $self = shift;
++    my $group = shift || $self->root();
++    my ($arg, $rarg);
++
++    while ($arg = shift) {
++        $rarg = ref($arg);
++        if ($rarg eq HASH)
++        {
++            $self->set_properties (\%PROPERTIES, $arg, $group);
++        }
++        elsif ($rarg eq ARRAY)
++        {
++            my $subgroup = $self->add_group($group);
++            $self->add_text ($subgroup, @{$arg} );
++        }
++        elsif ($rarg eq SCALAR)
++        {
++            $self->add_text (${$arg});
++        }
++        else
++        {
++            $self->add_raw ($group, split_text($arg));
++        }
++    }
++}
++
++sub rtf
++{
++    my $self = shift;
++
++    unless ($self->{fontCnt}) {
++        carp "No default font has been specified";
++    }
++
++    return emit_group @{$self->{DOCUMENT}};
++}
++
++1;
++
++__END__
++
++=head1 NAME
++
++RTF::Document - Perl extension for generating Rich Text (RTF) Files 
++
++=head1 DESCRIPTION
++
++RTF::Document is a module for generating Rich Text Format (RTF) documents
++that can be used by most text converters and word processors.
++
++For a listing of properties, consult the %DOCINFO and %PROPERTIES hashes
++in the source code.
++
++=head1 REQUIRED MODULES
++
++    Carp
++    POSIX
++    Convert::Units::Type 0.33
++
++=head1 EXAMPLE
++
++    use RTF::Document;
++
++    # Document properties
++
++    $rtf = new RTF::Document(
++      {
++        doc_page_width => '8.5in',
++        doc_page_height => '11in'
++      }
++    );
++
++    # Font definitions
++
++    $fAvantGarde = $rtf->add_font ("AvantGarde", 
++       { family=>swiss,
++         default=>1
++       } );
++    $fCourier = $rtf->add_font ("Courier",
++      { family=>monospace, pitch=>fixed, 
++        alternates=>["Courier New", "American Typewriter"] 
++      } );
++
++    # Color definitions
++
++    $cRed   = $rtf->add_color ( { red=>255 } );
++    $cGreen = $rtf->add_color ( { green=>128 } );
++    $cCustm = $rtf->add_color ( { red=>0x66, blue=>0x33, green=>0x33 } );
++
++    $cBlack = $rtf->add_color ( { name=>'black' } );
++    $cWhite = $rtf->add_color ( { gray=>'100%' } );
++
++    $cNavy = $rtf->add_color ( { blue=>'100%', gray=>'50%' } );
++
++    # style definitions
++
++    $sNormal = $rtf->add_style( "Normal",
++      { font=>$fAvantGarde, font_size=>'12pt',
++        color_foreground=>$cBlack },
++      { type=>paragraph, default=>1 }
++    );
++
++    $sGreen = $rtf->add_style( "Green",
++      { color_foreground=>$cGreen },
++      { type=>character, additive=>1 }
++    );
++
++    # Mix any combo of properties and text...
++
++    $rtf->add_text( $rtf->root(),
++       "Default text\n\n",
++
++       { bold=>1, underline=>continuous },
++       "Bold/Underlined Text\n\n",
++
++       { font_size=>'20pt', font=>$fCourier,
++         color_foreground=>$cRed },
++       "Bigger, Red and Monospaced.\n\n",
++
++       { style_default=>paragraph },
++       { style_default=>character },
++
++       "This is ",
++       [ { style=>$sGreen }, "green" ],
++       " styled.\n\n"
++
++    );
++
++    open FILE, ">MyFile.rtf";
++    binmode FILE;
++    print FILE $rtf->rtf();
++    close FILE;
++
++=head1 DOCUMENT STRUCTURE
++
++For purposes of using this module, a Rich Text (RTF) Document can be subdivided into
++I<groups>. Groups can be considered containers for I<text> and I<controls> (controlling
++document and text properties).
++
++For all intents and purposes, a group limits the scope of controls. So if we set
++the "bold" character property within a group, the text will be bold only within
++that group (until it is turned off within that group).
++
++When generating a RTF document using this module, we are only concerned with the
++I<root> group (also called the "Document Area"). (The "Header" groups are taken
++care of automatically by this module.)
++
++The Document Area is subdivided into I<sections>. Each section is subdivided into
++I<paragraphs>.
++
++=head1 METHODS
++
++Some of the methods are documented below. (Methods not documented here may
++be changed in future versions.)
++
++=head2 new
++
++    $rtf = new RTF::Document( \%DocumentProperties );
++
++Creates a new RTF document object.
++
++=head2 root
++
++    $gRoot = $rtf->root();
++
++Returns the "root" group in the RTF document.
++
++=head2 new_group
++
++    $gMyGroup = $rtf->new_group();
++
++Creates a new group (not inside of the RTF document).
++
++=head2 add_group
++
++    $gChildOfRoot = $rtf->add_group();
++    $gChildOfChild = $rtf->add_group( $gChild );
++
++Adds a child group to the specfied group. If no group is specified, the "root"
++group is assumed.
++
++    $rtf->add_group( $rtf->root(), $gMyGroup );
++
++Adds a group to the specified parent group (in this case, the root group).
++
++=head2 add_raw
++
++    $rtf->add_raw( $group, '\par', "Some Text" );
++
++Adds raw controls and text to the group. This method is intended for internal
++use only.
++
++=head2 add_text
++
++    $rtf->add_text( $group, "Some text ", { bold=>1 }, "more text" );
++
++Adds text and controls to a group. Text is escaped.
++
++=head2 add_font
++
++=head2 add_color
++
++=head2 add_style
++
++=head1 PROPERTIES
++
++=head2 Document Properties
++
++=head2 Section Properties
++
++=head2 Paragraph Properties
++
++=head2 Character Properties
++
++=head1 KNOWN ISSUES
++
++This module should be considered in the "alpha" stage. Use at your own risk.
++
++There are no default document or style properties produced by this module,
++with the exception of the character set. If you want to make sure that a
++I<specific> font, color, or style is used, you must specify it. Otherwise
++you rely on the assumptions of whatever RTF reader someone is using.
++
++This module does not insert newlines anywhere in the text, even though some
++RTF writers break lines before they exceed 225 characters.  This may or may
++not be an issue with some reader software.
++
++Unknown font or style properties will generally be ignored without warning.
++
++This module supports some newer RTF controls (used in Word 95/Word 97) that
++may are not understood by older RTF readers.
++
++Once a Font, Color or Style is added, it cannot be changed. No checking
++for redundant entries is done.
++
++Generally, it is not possible to reference a not-yet-created Style with the
++next or basedon attributes. However, you can use the constances "last",
++"self" or "next" to reference the last style added, the current style
++being added, or the next style that will be added, respectively.
++
++Specifying properties in a particular order within a group does not
++guarantee that they will be emitted in that order. If order matters,
++specify them separetly. For instance,
++
++    $rtf->add_text($rtf->root, { style_default=>character, bold=>1 } );
++
++should be (if you want to ensure character styles are reset before setting
++bold text):
++
++    $rtf->add_text($rtf->root, { style_default=>character }, { bold=>1 } );
++
++Also note that duplicate properties within the same group won't work. i.e.,
++If you want to set "style_default" for both paragraphs and characters, you
++must do so in separate groups.
++
++This isn't so much as a bug as the way Perl handles hashes.
++
++=head2 Unimplemented Features
++
++A rather large number of features and control words are not handled in this
++version. Among the major features:
++
++=over
++
++=item Annotations and Comments
++
++=item Bookmarks
++
++=item Bullets and Paragraph Numbering
++
++Some support has been added. The backwards-compatability controls for numbered
++paragraphs used by older readers has not been added because it is not properly
++handled by newer readers.
++
++=item Character Sets and Internationalization
++
++Non-"ANSI" character sets (i.e., Macintosh) and Unicode character
++sets are not supported (at least not intentionally). There is no
++support for Asian character sets in this version of the module.
++
++Unicode character escapes are not implemented.
++
++Language codes (defining a default language, or a language for a
++group of characters) are not implemented.
++
++Bi-directional and text-flow controls are not implemented.
++
++=item Embedded Images and OLE Objects
++
++=item File Tables
++
++=item Footnotes and Endnotes
++
++=item Forms
++
++=item Headers and Footers
++
++=item Hyphenation Control
++
++Some minimal controls have been added.
++
++=item Lists and List Tables
++
++Not implemented: List Tables are really a kind of style sheet for lists.
++Priority will be given to support generic bullets and paragraph numbering.
++
++=item Page Numbering
++
++Minimal definition, untested.
++
++=item Printer Bin Controls
++
++=item Revision Tables
++
++=item Special Characters and Document Variables
++
++Most special characters not not implemented, with the exception of tabs. Double
++newline characters are converted to a new paragraph control, and single newlines
++are converted to a new line control.
++
++=item Tabs
++
++=item Tables and Frames
++
++=back
++
++=head1 SEE ALSO
++
++Microsoft Technical Support and Application Note, "Rich Text Format (RTF)
++Specification and Sample Reader Program", Version 1.5.
++
++I<Convert::Units::Type>.
++
++=head1 AUTHOR
++
++Robert Rothenberg <wlkng...@unix.asb.com>
++
++=head1 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.
++
++=cut
++
diff --git a/debian/patches/01_make_it_strict.dpatch b/debian/patches/20-make-it-strict.patch
similarity index 99%
rename from debian/patches/01_make_it_strict.dpatch
rename to debian/patches/20-make-it-strict.patch
index 8faaa84..f5e53c8 100644
--- a/debian/patches/01_make_it_strict.dpatch
+++ b/debian/patches/20-make-it-strict.patch
@@ -1,6 +1,3 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-
-@DPATCH@
 --- Document.pm	2006-02-13 15:53:37.122539911 +0100
 +++ debian/Document.pm	2006-02-13 15:51:04.891781370 +0100
 @@ -14,6 +14,7 @@
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..bc7f5be
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,2 @@
+10-local-changes.patch
+20-make-it-strict.patch
diff --git a/debian/rules b/debian/rules
index 22fb31b..1d6fda2 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,7 +1,6 @@
 #!/usr/bin/make -f
 # -*- Makefile -*-
 
-include /usr/share/dpatch/dpatch.make
 
 # Make sure perl is defined (allow overriding from the command line
 PERL ?= /usr/bin/perl
@@ -43,8 +42,12 @@ binary-indep-stamp: arrange
 	dh_builddeb
 	touch binary-indep-stamp
 
+
+build-arch: build
+build-indep: build
+
 build: build-stamp
-build-stamp: patch config
+build-stamp: config
 	dh_testdir
 	$(MAKE)
 	$(MAKE) test
@@ -68,4 +71,4 @@ install-stamp: build
 	$(MAKE) install PREFIX=$(b)/usr
 	touch install-stamp
 
-.PHONY: arrange binary binary-arch binary-indep build clean config install patch
+.PHONY: arrange binary binary-arch binary-indep build clean config install
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
-- 
1.7.10


--- End Message ---
--- Begin Message ---
Source: librtf-document-perl
Source-Version: 0.64-11

We believe that the bug you reported is fixed in the latest version of
librtf-document-perl, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 670...@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Axel Beckert <a...@debian.org> (supplier of updated librtf-document-perl 
package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmas...@ftp-master.debian.org)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Format: 1.8
Date: Tue, 21 Jul 2015 22:54:43 +0200
Source: librtf-document-perl
Binary: librtf-document-perl
Architecture: source all
Version: 0.64-11
Distribution: unstable
Urgency: medium
Maintainer: Debian Perl Group <pkg-perl-maintain...@lists.alioth.debian.org>
Changed-By: Axel Beckert <a...@debian.org>
Description:
 librtf-document-perl - Perl extension for generating Rich Text Format (RTF) 
files
Closes: 670750 786681
Changes:
 librtf-document-perl (0.64-11) unstable; urgency=medium
 .
   * Team upload
   * Move package under the umbrella of the Debian Perl Group
     (c.f. https://lists.debian.org/debian-perl/2014/04/msg00033.html)
     + move Krzysztof Krzyzaniak (eloy) to Uploaders.
     + Added Vcs-* fields
   * Added ${misc:Depends} to Depends.
   * Apply wrap-and-sort.
   * Remove obsolete local emacs variables from debian/changelog.
   * Apply dpatch2quilt and switch to source format "3.0 (quilt)".
     + Add debian/source/format
     + Drop build-dependency on dpatch
     + Drop dependencies on patch target from debian/rules.
     + Obsoletes and hence closes: #670750.
   * Drop complete Diff of Document.pm by fixing the line-endings.
   * Replace Build-Dependency on perl5 by plain perl (Closes: #786681)
   * Rewrite debian/rules using a minimal dh v7 style file.
     + Stop installing upstream README, i.e. no debian/docs needed.
     + Bump debhelper compat level to 9, bump according versioned b-d.
   * Declare compliance with Debian Policy 3.9.6.
   * Rewrite debian/copyright in machine-readable DEP5 format.
   * Mark package as autopkgtestable.
   * Add a Homepage header and let it point the author's BackPAN directory.
   * Slightly optimize short and long package description.
   * Add patch to fix "defined(@array) is deprecated" warning.
Checksums-Sha1:
 9557c446e8b8255e80f97e06506b4099f1404cdc 2157 librtf-document-perl_0.64-11.dsc
 878b5bf36461948457af829ea3d934807b677a6d 5144 
librtf-document-perl_0.64-11.debian.tar.xz
 912e02f518a8c6d36bb2b27a9e256c71cf1358e4 19732 
librtf-document-perl_0.64-11_all.deb
Checksums-Sha256:
 ebe7d1d536ea0618876ceb96067ff293f4607973367e07bcd712bdc7c122fabb 2157 
librtf-document-perl_0.64-11.dsc
 23e023806c8e0e365810e72b145a8b313b41d25ee0860ca5b9d7121921d74164 5144 
librtf-document-perl_0.64-11.debian.tar.xz
 748d32d4c3772136268e7346dbd1bbee2c8aec607a281a7a425b24adfa80b72c 19732 
librtf-document-perl_0.64-11_all.deb
Files:
 9dbbadc372ddf4e7747b9a9d71d6da35 2157 perl extra 
librtf-document-perl_0.64-11.dsc
 11cf2acaa1929624d9facd282f211afe 5144 perl extra 
librtf-document-perl_0.64-11.debian.tar.xz
 2004cd64d869e27e9bc39366f616b0d8 19732 perl extra 
librtf-document-perl_0.64-11_all.deb

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBCAAGBQJVrrHyAAoJEGvmY8daNcl1OmMP/ixa/x/rjWljAihy5lRdly+f
Chez+lLEzYRAL+0cQ1CP6TJPlCGc56WbTUjVkGRYN7ujePhvDZI3DiIkhaDYryte
EqE8pnZIcO/WgIblNVkfzwFC6w2xKTXxtV3PgK6Gl0Kp63zMCoYKITisKslT7mDt
0TYo8bVL5lhr3k5SdNwzUrBjLkUbsP/36Y+HdZsd3DTP4WLXQ/kP9MC4DXmEbezV
KURJsXC1GmtBPABeeUiWfAfjvrOLauhL8QVhZYg4VC0qMCp/W8x0OZPAKi/fgEKd
MeaLKxDf/qlt9AcIK2HlPE3J+az9GPVH4SmKtuk9S6Cy4+Fe7ItrhmMPiNZ0933E
Aqmsf4C2QT2LxGEQ7J/GBbNaKuWMW1vlb7pEaWeLSDbSrSAcCKPtJRpTd0/gwepn
1a+j0GHkEQ+vqWNxoA4N5a+dWzdVkRFm65KZmH1C9dHzDBBWW+vyL09uKoMIkLeJ
RJ4PD5VdvFAVul39ZPqOjfHLMNqIWwR85t7QDC9ESSCf2WkRjj1aW19Kf+bh2Toh
Cjzg/MECIszD3Hfgsesl1bLP8erD5xXFGwj56skgBpNsyp540ruLkoOOdo57EpLo
0TE+FBpiLywh/+KK86nf7jSEQJEDxYJWI9JL/CmeWO7fSv0jSU2eH9zGehfo/uPW
wQiNEhFImUwq/nEJWl90
=g3Nw
-----END PGP SIGNATURE-----

--- End Message ---

Reply via email to