Finished changes for v0.21 - including documentation fixes and a new renderer
[p5sagit/Excel-Template.git] / lib / Excel / Template.pm
index b5780af..2c130fc 100644 (file)
@@ -6,15 +6,24 @@ BEGIN {
     use Excel::Template::Base;
     use vars qw ($VERSION @ISA);
 
-    $VERSION  = '0.12';
+    $VERSION  = '0.21';
     @ISA      = qw( Excel::Template::Base );
 }
 
 use File::Basename;
 use XML::Parser;
-use IO::File;
 use IO::Scalar;
 
+use constant RENDER_NML => 'normal';
+use constant RENDER_BIG => 'big';
+use constant RENDER_XML => 'xml';
+
+my %renderers = (
+    RENDER_NML, 'Spreadsheet::WriteExcel',
+    RENDER_BIG, 'Spreadsheet::WriteExcel::Big',
+    RENDER_XML, 'Spreadsheet::WriteExcelXML',
+);
+
 sub new
 {
     my $class = shift;
@@ -24,8 +33,21 @@ sub new
         if defined $self->{FILENAME};
 
     my @renderer_classes = ( 'Spreadsheet::WriteExcel' );
-    if (exists $self->{BIG_FILE} && $self->{BIG_FILE})
+
+    if (exists $self->{RENDERER} && $self->{RENDERER})
+    {
+        if (exists $renderers{ lc $self->{RENDERER} })
+        {
+            unshift @renderer_classes, $renderers{ lc $self->{RENDERER} };
+        }
+        elsif ($^W)
+        {
+            warn "'$self->{RENDERER}' is not recognized\n";
+        }
+    }
+    elsif (exists $self->{BIG_FILE} && $self->{BIG_FILE})
     {
+        warn "Use of BIG_FILE is deprecated.\n";
         unshift @renderer_classes, 'Spreadsheet::WriteExcel::Big';
     }
 
@@ -38,7 +60,7 @@ sub new
             $class->import;
         };
         if ($@) {
-            warn "Could not find or compile '$class'\n";
+            warn "Could not find or compile '$class'\n" if $^W;
         } else {
             $self->{RENDERER} = $class;
             last;
@@ -50,6 +72,9 @@ sub new
             join("\n\t", @renderer_classes) .
             "\n";
 
+    $self->{USE_UNICODE} = ~~0
+        if $] >= 5.008;
+
     return $self;
 }
 
@@ -67,7 +92,7 @@ sub param
     $params{uc $_} = delete $params{$_} for keys %params;
     @{$self->{PARAM_MAP}}{keys %params} = @params{keys %params};
 
-    return 1;
+    return ~~1;
 }
 
 sub write_file
@@ -82,7 +107,7 @@ sub write_file
 
     $xls->close;
 
-    return 1;
+    return ~~1;
 }
 
 sub output
@@ -97,13 +122,6 @@ sub output
     return $output;
 }
 
-sub parse
-{
-    my $self = shift;
-
-    $self->parse_xml(@_);
-}
-
 sub parse_xml
 {
     my $self = shift;
@@ -120,14 +138,14 @@ sub parse_xml
 
                 my $name = uc shift;
 
-                my $node = Excel::Template::Factory->create_node($name, @_);
+                my $node = Excel::Template::Factory->_create_node($name, @_);
                 die "'$name' (@_) didn't make a node!\n" unless defined $node;
 
-                if ($name eq 'WORKBOOK')
+                if ( $node->isa( 'WORKBOOK' ) )
                 {
                     push @{$self->{WORKBOOKS}}, $node;
                 }
-                elsif ($name eq 'VAR')
+                elsif ( $node->is_embedded )
                 {
                     return unless @stack;
                                                                                 
@@ -169,32 +187,34 @@ sub parse_xml
     );
 
     {
-        my $fh = IO::File->new($fname)
+        open( INFILE, "<$fname" )
             || die "Cannot open '$fname' for reading: $!\n";
 
-        $parser->parse(do { local $/ = undef; <$fh> });
+        $parser->parse(do { local $/ = undef; <INFILE> });
 
-        $fh->close;
+        close INFILE;
     }
 
-    return 1;
+    return ~~1;
 }
+*parse = \&parse_xml;
 
 sub _prepare_output
 {
     my $self = shift;
     my ($xls) = @_;
 
-    my $context = Excel::Template::Factory->create(
+    my $context = Excel::Template::Factory->_create(
         'CONTEXT',
 
         XLS       => $xls,
         PARAM_MAP => [ $self->{PARAM_MAP} ],
+        UNICODE   => $self->{UNICODE},
     );
 
     $_->render($context) for @{$self->{WORKBOOKS}};
 
-    return 1;
+    return ~~1;
 }
 
 sub register { shift; Excel::Template::Factory::register(@_) }
@@ -223,7 +243,7 @@ For example, test.xml:
 Now, create a small program to use it:
 
   #!/usr/bin/perl -w
-  use Excel::Template
+  use Excel::Template;
 
   # Create the Excel template
   my $template = Excel::Template->new(
@@ -256,9 +276,6 @@ need to use the same datastructure as HTML::Template, but provide Excel files
 instead. The existing modules don't do the trick, as they require replication
 of logic that's already been done within HTML::Template.
 
-Currently, only a small subset of the planned features are supported. This is
-meant to be a test of the waters, to see what features people actually want.
-
 =head1 MOTIVATION
 
 I do a lot of Perl/CGI for reporting purposes. In nearly every place I've been,
@@ -272,15 +289,60 @@ into an XLS file.
 
 =head2 new()
 
-This creates a Excel::Template object. If passed a filename parameter, it will
+This creates a Excel::Template object. If passed a FILENAME parameter, it will
 parse the template in the given file. (You can also use the parse() method,
 described below.)
 
+=head3 Parameters
+
+=over 4
+
+=item * RENDERER
+
+The default rendering engine is Spreadsheet::WriteExcel. You may, if you choose, change that to another choice. The legal values are:
+
+=over 4
+
+=item * Excel::Template->RENDER_NML
+
+This is the default of Spreadsheet::WriteExcel.
+
+=item * Excel::Template->RENDER_BIG
+
+This attempts to load Spreadsheet::WriteExcel::Big.
+
+=item * Excel::Template->RENDER_XML
+
+This attempts to load Spreadsheet::WriteExcelXML.
+
+=back
+
+=item * USE_UNICODE
+
+This will use L<Unicode::String> to represent strings instead of Perl's internal string handling. You must already have L<Unicode::String> installed on your system.
+
+The USE_UNICODE parameter will be ignored if you are using Perl 5.8 or higher as
+Perl's internal string handling is unicode-aware.
+
+NOTE: Certain older versions of L<OLE::Storage_Lite> and mod_perl clash for some
+reason. Upgrading to the latest version of L<OLE::Storage_Lite> should fix the
+problem.
+
+=back
+
+=head3 Deprecated
+
+=over 4
+
+=item * BIG_FILE
+
+Instead, use RENDERER => Excel::Template->RENDER_BIG
+
+=back
+
 =head2 param()
 
-This method is exactly like HTML::Template's param() method. Although I will
-be adding more to this section later, please see HTML::Template's description
-for info right now.
+This method is exactly like L<HTML::Template>'s param() method.
 
 =head2 parse() / parse_xml()
 
@@ -299,35 +361,71 @@ It will act just like HTML::Template's output() method, returning the resultant
 file as a stream, usually for output to the web. (This is when the actual
 merging of the template and the parameters occurs.)
 
+=head2 register()
+
+This allows you to register a class as handling a node. q.v. L<Excel::Template::Factory> for more info.
+
 =head1 SUPPORTED NODES
 
-This is just a list of nodes. See the other classes in this distro for more
+This is a partial list of nodes. See the other classes in this distro for more
 details on specific parameters and the like.
 
 Every node can set the ROW and COL parameters. These are the actual ROW/COL
-values that the next CELL tag will write into.
+values that the next CELL-type tag will write into.
 
 =over 4
 
-=item * WORKBOOK
+=item * L<WORKBOOK|Excel::Template::Container::Workbook>
+
+This is the node representing the workbook. It is the parent for all other
+nodes.
+
+=item * L<WORKSHEET|Excel::Template::Container::Worksheet>
+
+This is the node representing a given worksheet.
 
-=item * WORKSHEET
+=item * L<IF|Excel::Template::Container::Conditional>
 
-=item * IF
+This node represents a conditional expression. Its children may or may not be
+rendered. It behaves just like L<HTML::Template>'s TMPL_IF.
 
-=item * LOOP
+=item * L<LOOP|Excel::Template::Container::Loop>
 
-=item * ROW
+This node represents a loop. It behaves just like L<HTML::Template>'s TMPL_LOOP.
 
-=item * CELL
+=item * L<ROW|Excel::Template::Container::Row>
 
-=item * FORMULA
+This node represents a row of data. This is the A in A1.
 
-=item * BOLD
+=item * L<FORMAT|Excel::Template::Container::Format>
 
-=item * ITALIC
+This node varies the format for its children. All formatting options supported
+in L<Spreadsheet::WriteExcel> are supported here. There are also a number of
+formatting shortcuts, such as L<BOLD|Excel::Template::Container::Bold> and
+L<ITALIC|Excel::Template::Container::Italic>.
 
-=back 4
+=item * L<BACKREF|Excel::Template::Element::Backref>
+
+This refers back to a cell previously named.
+
+=item * L<CELL|Excel::Template::Element::Cell>
+
+This is the actual cell in a spreadsheet.
+
+=item * L<FORMULA|Excel::Template::Element::Formula>
+
+This is a formula in a spreadsheet.
+
+=item * L<RANGE|Excel::Template::Element::Range>
+
+This is a BACKREF for a number of identically-named cells.
+
+=item * L<VAR|Excel::Template::Element::Var>
+
+This is a variable. It is generally used when the 'text' attribute isn't
+sufficient.
+
+=back
 
 =head1 BUGS
 
@@ -335,17 +433,66 @@ None, that I know of.
 
 =head1 SUPPORT
 
-This is currently beta-quality software. The featureset is extremely limited,
-but I expect to be adding on to it very soon.
+This is production quality software, used in several production web
+applications.
 
 =head1 AUTHOR
 
-    Rob Kinyon
-    rob.kinyon@gmail.com
+    Rob Kinyon (rob.kinyon@gmail.com)
 
 =head1 CONTRIBUTORS
 
-There is a mailing list at http://groups-beta.google.com/group/ExcelTemplate
+There is a mailing list at http://groups.google.com/group/ExcelTemplate or exceltemplate@googlegroups.com
+
+=head2 Robert Graff
+
+=over 4
+
+=item * Finishing formats
+
+=item * Fixing several bugs in worksheet naming
+
+=back
+
+=head1 TEST COVERAGE
+
+I used Devel::Cover to test the coverage of my tests. Every release, I intend to improve these numbers.
+
+Excel::Template is also part of the CPAN Kwalitee initiative, being one of the top 100 non-core modules downloaded from CPAN. If you wish to help out, please feel free to contribute tests, patches, and/or suggestions.
+
+---------------------------- ------ ------ ------ ------ ------ ------ ------
+File                           stmt branch   cond    sub    pod   time  total
+---------------------------- ------ ------ ------ ------ ------ ------ ------
+blib/lib/Excel/Template.pm     90.0   57.1   50.0   90.5  100.0   26.0   80.8
+...ib/Excel/Template/Base.pm   83.3   50.0   66.7   75.0   88.9    8.8   80.0
+...cel/Template/Container.pm   46.3   20.0   33.3   58.3   85.7    4.6   47.7
+...emplate/Container/Bold.pm  100.0    n/a    n/a  100.0    0.0    0.6   95.0
+.../Container/Conditional.pm   58.5   52.3   66.7   75.0   66.7    0.7   58.4
+...plate/Container/Format.pm  100.0    n/a    n/a  100.0    0.0    0.8   96.6
+...plate/Container/Hidden.pm  100.0    n/a    n/a  100.0    0.0    0.2   95.0
+...plate/Container/Italic.pm  100.0    n/a    n/a  100.0    0.0    0.2   95.0
+...plate/Container/Locked.pm  100.0    n/a    n/a  100.0    0.0    0.1   95.0
+...emplate/Container/Loop.pm   55.6   40.0   50.0   77.8   75.0    0.5   56.6
+...late/Container/Outline.pm   71.4    n/a    n/a   80.0    0.0    0.0   70.0
+...Template/Container/Row.pm  100.0   75.0    n/a  100.0   50.0    0.3   93.8
+...mplate/Container/Scope.pm  100.0    n/a    n/a  100.0    n/a    0.1  100.0
+...plate/Container/Shadow.pm  100.0    n/a    n/a  100.0    0.0    0.1   95.0
+...te/Container/Strikeout.pm  100.0    n/a    n/a  100.0    0.0    0.1   95.0
+...ate/Container/Workbook.pm  100.0    n/a    n/a  100.0    n/a    1.1  100.0
+...te/Container/Worksheet.pm   94.1   50.0    n/a  100.0    0.0    0.9   88.0
+...Excel/Template/Context.pm   83.1   53.4   54.2   95.0   92.9   19.2   75.2
+...Excel/Template/Element.pm  100.0    n/a    n/a  100.0    n/a    0.5  100.0
+...mplate/Element/Backref.pm  100.0   50.0   33.3  100.0    0.0    0.1   87.1
+.../Template/Element/Cell.pm   95.8   65.0   80.0  100.0   66.7    3.6   86.9
+...mplate/Element/Formula.pm  100.0    n/a    n/a  100.0    0.0    0.3   94.1
+...Template/Element/Range.pm  100.0   66.7    n/a  100.0   66.7    0.2   93.3
+...l/Template/Element/Var.pm  100.0    n/a    n/a  100.0    0.0    0.2   94.1
+...Excel/Template/Factory.pm   57.1   34.6    n/a   88.9  100.0   15.4   55.2
+.../Excel/Template/Format.pm   98.3   81.2   33.3  100.0  100.0    9.9   93.2
+...xcel/Template/Iterator.pm   85.2   70.6   70.6   84.6   87.5    2.0   80.4
+...el/Template/TextObject.pm   92.9   62.5   33.3  100.0   50.0    3.6   83.0
+Total                          83.0   55.6   57.0   91.1   98.7  100.0   78.6
+---------------------------- ------ ------ ------ ------ ------ ------ ------
 
 =head1 COPYRIGHT