Revision history for Perl distribution Excel::Template
0.24 ??? Mar 0? ??:00:00 2005
+ - Implemented the KEEP_LEADING_ZEROS node
+ - This wraps the keep_leading_zeros() worksheet method
- Improved code coverage with more and better tests
+ - Improved POD linking
+ - Every module/node reference in POD should link to the appropriate POD
0.23 Fri Feb 25 15:00:00 2005
- Improved code coverage with more and better tests
lib/Excel/Template/Container/Format.pm
lib/Excel/Template/Container/Hidden.pm
lib/Excel/Template/Container/Italic.pm
+lib/Excel/Template/Container/KeepLeadingZeros.pm
lib/Excel/Template/Container/Loop.pm
lib/Excel/Template/Container/Locked.pm
lib/Excel/Template/Container/Outline.pm
t/018_register.t
t/019_output.t
t/020_worksheet_attributes.t
+t/021_loop_error.t
+t/022_keep_leading_zeros.t
t/998_pod.t
t/999_pod_coverage.t
t/mock.pm
# Devel::Cover
^cover_db/?
^tags?
-.err?
# developer-only tests
-^dev_.*\.t$
+^t/dev_.*\.t$
/^ge$/ && do { $res = ($val ge $value); last };
/^le$/ && do { $res = ($val le $value); last };
- die "Unknown operator in conditional resolve", $/;
+ die "Unknown operator '$op' in conditional resolve", $/;
}
return $res && 1;
=head1 INHERITANCE
-Excel::Template::Container
+L<CONTAINER|Excel::Template::Container>
=head1 ATTRIBUTES
=item * NAME
-This is the name of the parameter to be testing. It is resolved like any other
-parameter.
+This is the name of the parameter to test. It is resolved like any other parameter name. (q.v. L<VAR|Excel::Template::Element::Var> for more info.)
=item * VALUE
-If VALUE is set, then a comparison operation is done. The value of NAME is
-compared to VALUE using the value of OP.
+If VALUE is set, then a comparison operation is done. The value of NAME is compared to VALUE using the value of OP.
=item * OP
-If VALUE is set, then this is checked. If it isn't present, then '==' (numeric
-equality) is assumed. OP must be one of the numeric comparison operators or the
-string comparison operators. All 6 of each kind is supported.
+If VALUE is set, then this is checked. If it isn't present, then '==' (numeric equality) is assumed. OP must be one of Perl the numeric comparison operators or the string comparison operators. All 6 of each kind is supported.
+
+B<Note>: If you want to use < or <=, you must instead use < or <=. This is to make sure it will parse with L<XML::Parser>. You should not need to use > or >= instead of > and >=, respectively.
=item * IS
-If VALUE is not set, then IS is checked. IS is allowed to be either "TRUE" or
-"FALSE". The boolean value of NAME is checked against IS.
+If VALUE is not set, then IS is checked. IS is allowed to be either "TRUE" or "FALSE". The boolean value of NAME is checked against IS.
=back
... Children here
</if>
-In the above example, the children will be executed if the value of __ODD__
-(which is set by the LOOP node) is false. So, for all even iterations.
+In the above example, the children will be executed if the value of __ODD__ (which is set by the L<LOOP|Excel::Template::Container::Loop> node) is false. So, for all even iterations.
=head1 AUTHOR
=head1 SEE ALSO
-LOOP
+L<LOOP|Excel::Template::Container::Loop>, L<VAR|Excel::Template::Element::Var>
=cut
--- /dev/null
+package Excel::Template::Container::KeepLeadingZeros;
+
+use strict;
+
+BEGIN {
+ use vars qw(@ISA);
+ @ISA = qw(Excel::Template::Container);
+
+ use Excel::Template::Container;
+}
+
+sub render
+{
+ my $self = shift;
+ my ($context) = @_;
+
+ my $worksheet = $context->active_worksheet;
+
+ $worksheet
+ ? $worksheet->keep_leading_zeros( 1 )
+ : $context->mark( keep_leading_zeros => 1 );
+
+ my $rv = $self->SUPER::render($context);
+
+ $worksheet
+ ? $worksheet->keep_leading_zeros( 0 )
+ : $context->mark( keep_leading_zeros => 0 );
+
+ return $rv;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Excel::Template::Container::KeepLeadingZeros - Excel::Template::Container::KeepLeadingZeros
+
+=head1 PURPOSE
+
+To set the keep_leading_zeros flag for the surrounding worksheet or any worksheets that might be contained within this node.
+
+=head1 NODE NAME
+
+KEEP_LEADING_ZEROS
+
+=head1 INHERITANCE
+
+L<CONTAINER|Excel::Template::Container>
+
+=head1 ATTRIBUTES
+
+None
+
+=head1 CHILDREN
+
+None
+
+=head1 EFFECTS
+
+Alters how leading zeros are interpreted by L<Spreadsheet::WriteExcel>.
+
+=head1 DEPENDENCIES
+
+None
+
+=head1 USAGE
+
+ <worksheet>
+ ... Cells here will NOT have leading-zeros preserved
+ <keep_leading_zeros>
+ ... Cells here will have leading-zeros preserved
+ </keep_leading_zeros>
+ ... Cells here will NOT have leading-zeros preserved
+ </worksheet>
+
+ <keep_leading_zeros>
+ <worksheet>
+ ... Cells here will have leading-zeros preserved
+ </worksheet>
+ <worksheet>
+ ... Cells here will have leading-zeros preserved
+ </worksheet>
+ </keep_leading_zeros>
+
+=head1 AUTHOR
+
+Rob Kinyon (rob.kinyon@gmail.com)
+
+=head1 SEE ALSO
+
+L<CELL|Excel::Template::Element::Cell>, L<Spreadsheet::WriteExcel>
+
+=cut
use Excel::Template::Container;
}
+sub exit_scope { $_[1]->active_worksheet( undef ) }
+
sub render
{
my $self = shift;
my ($context) = @_;
- $context->new_worksheet( $self );
+ my $worksheet = $context->new_worksheet( $self );
my $password = $context->get( $self, 'PROTECT' );
if (defined $password)
{
- $context->active_worksheet->protect( $password );
+ $worksheet->protect( $password );
}
- my $keep_zeros = $context->get( $self, 'KEEP_LEADING_ZEROS' );
- if ( defined $keep_zeros )
- {
- $context->active_worksheet->keep_leading_zeros( $keep_zeros ? 1 : 0 );
- }
+ $worksheet->keep_leading_zeros( 1 )
+ if $context->mark( 'keep_leading_zeros' );
return $self->SUPER::render($context);
}
$self->{ACTIVE_FORMAT} = Excel::Template::Format->blank_format($self);
$self->{WORKSHEET_NAMES} = undef;
+ $self->{__MARKS} = {};
+
# Removed NAME_MAP until I figure out what the heck it's for
for (qw( STACK PARAM_MAP ))
{
# 2) A decimal number
#GGG Convert this to use //x
- my ($op, $val) = $obj_val =~ m!^\s*([\+\*\/\-])?\s*([\d.]*\d)\s*$!oi;
+ my ($op, $val) = $obj_val =~ m/^\s*([\+\*\/\-])?\s*([\d.]*\d)\s*$/oi;
# Unless it's a relative value, we have what we came for.
return $obj_val unless $op;
$name = '';
}
- $self->active_worksheet(
+ return $self->active_worksheet(
$self->{XLS}->add_worksheet( $name ),
);
}
+sub mark
+{
+ my $self = shift;
+
+ if ( @_ > 1 )
+ {
+ my %args = @_;
+
+ @{$self->{__MARKS}}{keys %args} = values %args;
+ }
+
+ return $self->{__MARKS}{$_[0]}
+}
+
sub active_worksheet
{
my $self = shift;
=head2 get_last_reference
-=head2 named_param
+=head2 mark
=head2 new_worksheet
{
my $class = shift;
my $self = $class->SUPER::new(@_);
-
+
$self->{TXTOBJ} = Excel::Template::Factory->_create('TEXTOBJECT');
-
+
return $self;
}
{
my $self = shift;
my ($context) = @_;
-
+
my $txt = $context->get($self, 'TEXT');
if (defined $txt)
{
push @{$txt_obj->{STACK}}, $txt;
$txt = $txt_obj->resolve($context);
}
- elsif ($self->{TXTOBJ})
- {
- $txt = $self->{TXTOBJ}->resolve($context)
- }
else
{
- $txt = $context->use_unicode
- ? Unicode::String::utf8('')
- : '';
+ $txt = $self->{TXTOBJ}->resolve($context)
}
-
+
return $txt;
}
my ($row, $col) = map { $context->get($self, $_) } qw(ROW COL);
- my $ref = uc $context->get( $self, 'REF' );
+ my $ref = $context->get( $self, 'REF' );
if (defined $ref && length $ref)
{
- $context->add_reference( $ref, $row, $col );
+ $context->add_reference( uc( $ref ), $row, $col );
}
# Apply the cell width to the current column
{
$context->active_worksheet->set_column($col, $col, $width);
}
- }
+ }
$context->active_worksheet->$method(
$row, $col,
=head1 INHERITANCE
-Excel::Template::Element
+L<ELEMENT|Excel::Template::Element>
=head1 ATTRIBUTES
=item * TEXT
-This is the text to write to the cell. This can either be text or a parameter
-with a dollar-sign in front of the parameter name.
+This is the text to write to the cell. This can either be text or a parameter with a dollar-sign in front of the parameter name.
=item * COL
-Optionally, you can specify which column you want this cell to be in. It can be
-either a number (zero-based) or an offset. See Excel::Template for more info on
-offset-based numbering.
+Optionally, you can specify which column you want this cell to be in. It can be either a number (zero-based) or an offset. See L<Excel::Template> for more info on offset-based numbering.
=item * REF
-Adds the current cell to the a list of cells that can be backreferenced.
-This is useful when the current cell needs to be referenced by a
-formula. See BACKREF and RANGE.
+Adds the current cell to the a list of cells that can be backreferenced. This is useful when the current cell needs to be referenced by a formula. See L<BACKREF|Excel::Tepmlate::Element::Backref> and L<RANGE|Excel::Tepmlate::Container::Range>.
=item * WIDTH
=item * TYPE
-This allows you to specify what write_*() method will be used. The default is to
-call write() and let S::WE make the right call. However, you may wish to
-override it. Excel::Template will not do any form of validation on what you
-provide. You are assumed to know what you're doing.
+This allows you to specify what write_*() method will be used. The default is to call write() and let L<Spreadsheet::WriteExcel> make the right call. However, you may wish to override it. L<Excel::Template> will not do any form of validation on what you provide. You are assumed to know what you're doing.
-The legal types are:
+The legal types (taken from L<Spreadsheet::WriteExcel>) are:
=over 4
=head1 CHILDREN
-Excel::Template::Element::Formula
+L<FORMULA|Excel::Template::Element::Formula>
=head1 EFFECTS
-This will consume one column on the current row.
+This will consume one column in the current row.
=head1 DEPENDENCIES
<cell text="$Param2"/>
<cell>Some <var name="Param"> text here</cell>
-In the above example, four cells are written out. The first two have text hard-
-coded. The second two have variables. The third and fourth items have another
-thing that should be noted. If you have text where you want a variable in the
-middle, you have to use the latter form. Variables within parameters are the
-entire parameter's value.
+In the above example, four cells are written out. The first two have text hard-coded. The second two have variables. The third and fourth items have another thing that should be noted. If you have text where you want a variable in the middle, you have to use the latter form. Variables within parameters are the entire parameter's value.
-Please see Spreadsheet::WriteExcel for what constitutes a legal formula.
+Please see L<Spreadsheet::WriteExcel> for what constitutes a legal formula.
=head1 AUTHOR
=head1 SEE ALSO
-ROW, VAR, FORMULA
+L<ROW|Excel::Template::Container::Row>, L<VAR|Excel::Template::Element::Var>, L<FORMULA|Excel::Template::Element::Formula>
=cut
'SHADOW' => 'Excel::Template::Container::Shadow',
'STRIKEOUT' => 'Excel::Template::Container::Strikeout',
+ 'KEEP_LEADING_ZEROS' => 'Excel::Template::Container::KeepLeadingZeros',
+
# These are the helper objects
# They are also in here to make E::T::Factory::isa() work.
'CONTEXT' => 'Excel::Template::Context',
my %isBuildable = map { $_ => ~~1 } qw(
WORKBOOK WORKSHEET
FORMAT BOLD HIDDEN ITALIC LOCKED OUTLINE SHADOW STRIKEOUT
- IF ROW LOOP SCOPE
+ IF ROW LOOP SCOPE KEEP_LEADING_ZEROS
CELL FORMULA
VAR BACKREF RANGE
);
<loop name="loopy">
<row>
<if name="int">
- <cell text="bool" />
+ <cell text="bool true" />
</if>
<if name="int" is="FALSE">
- <cell text="not bool" />
+ <cell text="bool false" />
</if>
<if name="int" op="==" value="0">
- <cell text="int" />
+ <cell text="num == passes" />
+ </if>
+ <if name="int" op="!=" value="0">
+ <cell text="num != passes" />
+ </if>
+ <if name="int" op=">" value="0">
+ <cell text="num > passes" />
+ </if>
+ <if name="int" op=">=" value="0">
+ <cell text="num >= passes" />
+ </if>
+ <if name="int" op='<' value="0">
+ <cell text="num < passes" />
+ </if>
+ <if name="int" op="<=" value="0">
+ <cell text="num <= passes" />
</if>
<if name="char" op="eq" value="y">
- <cell text="char" />
+ <cell text="char eq passes" />
+ </if>
+ <if name="char" op="ne" value="y">
+ <cell text="char ne passes" />
+ </if>
+ <if name="char" op="gt" value="y">
+ <cell text="char gt passes" />
+ </if>
+ <if name="char" op="ge" value="y">
+ <cell text="char ge passes" />
+ </if>
+ <if name="char" op="lt" value="y">
+ <cell text="char lt passes" />
+ </if>
+ <if name="char" op="le" value="y">
+ <cell text="char le passes" />
</if>
</row>
</loop>
loopy => [
{ int => 0, char => 'n' },
{ int => 0, char => 'y' },
- { int => 1, char => 'n' },
- { int => 1, char => 'y' },
+ { int => 1, char => 'z' },
+ { int => -1, char => 'y' },
],
),
'Parameters set',
Spreadsheet::WriteExcel::add_format( '' )
Spreadsheet::WriteExcel::add_worksheet( 'conditional' )
Spreadsheet::WriteExcel::Worksheet::new( '' )
-Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'not bool', '1' )
-Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'int', '1' )
-Spreadsheet::WriteExcel::Worksheet::write( '1', '0', 'not bool', '1' )
-Spreadsheet::WriteExcel::Worksheet::write( '1', '1', 'int', '1' )
-Spreadsheet::WriteExcel::Worksheet::write( '1', '2', 'char', '1' )
-Spreadsheet::WriteExcel::Worksheet::write( '2', '0', 'bool', '1' )
-Spreadsheet::WriteExcel::Worksheet::write( '3', '0', 'bool', '1' )
-Spreadsheet::WriteExcel::Worksheet::write( '3', '1', 'char', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'bool false', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'num == passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '2', 'num >= passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '3', 'num <= passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '4', 'char ne passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '5', 'char lt passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '6', 'char le passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '1', '0', 'bool false', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '1', '1', 'num == passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '1', '2', 'num >= passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '1', '3', 'num <= passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '1', '4', 'char eq passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '1', '5', 'char ge passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '1', '6', 'char le passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '2', '0', 'bool true', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '2', '1', 'num != passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '2', '2', 'num > passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '2', '3', 'num >= passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '2', '4', 'char ne passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '2', '5', 'char gt passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '2', '6', 'char ge passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '3', '0', 'bool true', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '3', '1', 'num != passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '3', '2', 'num < passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '3', '3', 'num <= passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '3', '4', 'char eq passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '3', '5', 'char ge passes', '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '3', '6', 'char le passes', '1' )
Spreadsheet::WriteExcel::close( '' )
__END_EXPECTED__
Spreadsheet::WriteExcel::add_format( '' )
Spreadsheet::WriteExcel::add_worksheet( 'worksheet attributes' )
Spreadsheet::WriteExcel::Worksheet::new( '' )
-Spreadsheet::WriteExcel::Worksheet::keep_leading_zeros( '1' )
Spreadsheet::WriteExcel::Worksheet::write( '0', '0', '03', '1' )
Spreadsheet::WriteExcel::close( '' )
__END_EXPECTED__
__DATA__
<workbook>
- <worksheet name="worksheet attributes" keep_leading_zeros="1">
+ <worksheet name="worksheet attributes">
<cell text="03" />
</worksheet>
</workbook>
--- /dev/null
+BEGIN{ $^W = 0 }
+use strict;
+
+use Test::More tests => 4;
+
+use lib 't';
+use mock;
+mock::reset;
+
+my $CLASS = 'Excel::Template';
+use_ok( $CLASS );
+
+my $object = $CLASS->new(
+ file => \*DATA,
+);
+isa_ok( $object, $CLASS );
+
+ok( $object->write_file( 'filename' ), 'Successfuly wrote file' );
+
+my @calls = mock::get_calls;
+is( join( $/, @calls, '' ), <<__END_EXPECTED__, 'Calls match up' );
+Spreadsheet::WriteExcel::new( 'filename' )
+Spreadsheet::WriteExcel::add_format( '' )
+Spreadsheet::WriteExcel::add_worksheet( '' )
+Spreadsheet::WriteExcel::Worksheet::new( '' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'before', '1' )
+Spreadsheet::WriteExcel::Worksheet::keep_leading_zeros( '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '1', 'inside', '1' )
+Spreadsheet::WriteExcel::Worksheet::keep_leading_zeros( '0' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '2', 'after', '1' )
+Spreadsheet::WriteExcel::add_worksheet( '' )
+Spreadsheet::WriteExcel::Worksheet::new( '' )
+Spreadsheet::WriteExcel::Worksheet::keep_leading_zeros( '1' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'within', '1' )
+Spreadsheet::WriteExcel::add_worksheet( '' )
+Spreadsheet::WriteExcel::Worksheet::new( '' )
+Spreadsheet::WriteExcel::Worksheet::write( '0', '0', 'after', '1' )
+Spreadsheet::WriteExcel::close( '' )
+__END_EXPECTED__
+
+__DATA__
+<workbook>
+ <worksheet>
+ <cell text="before" />
+ <keep_leading_zeros>
+ <cell text="inside" />
+ </keep_leading_zeros>
+ <cell text="after" />
+ </worksheet>
+ <keep_leading_zeros>
+ <worksheet>
+ <cell text="within" />
+ </worksheet>
+ </keep_leading_zeros>
+ <worksheet>
+ <cell text="after" />
+ </worksheet>
+</workbook>
+