package Spreadsheet::WriteExcelXML::XMLwriter; ############################################################################### # # XMLwriter - An abstract base class for Excel workbooks and worksheets. # # # Used in conjunction with Spreadsheet::WriteExcelXML # # Copyright 2000-2004, John McNamara, jmcnamara@cpan.org # # Documentation after __END__ # use Exporter; use strict; use vars qw($VERSION @ISA); @ISA = qw(Exporter); $VERSION = '0.01'; ############################################################################### # # new() # # Constructor # sub new { my $class = $_[0]; my $self = { _indentation => " ", _filehandle => undef, _no_encoding => 0, _printed => 1, }; bless $self, $class; return $self; } ############################################################################### # # _format_tag($level, $nl, $list, @attributes) # # This function formats an XML element tag for printing. Adds indentation and # newlines as specified. Keeps attributes, if any, on one line or formats # them one per line. # # Args: # $level = The indentation level (int) # $nl = Number of newlines after tag (int) # $list = List attributes on separate lines (0, 1, 2) # 0 = No list # 1 = Automatic list # 2 = Explicit list # @attributes = Attribute/Value pairs # # The list option puts the attributes on separate lines if there if there is # more than one attribute. List option 2 generates this effect even when there # is only one attribute. # sub _format_tag { my $self = shift; my $level = shift; my $nl = shift; my $list = shift; my $element = $self->{_indentation} x $level. '<' . shift; # Autolist option. Only use list format if there is more than 1 attribute. $list = 0 if $list == 1 and @_ <= 2; # Special case. If _indentation is "" avoid all unnecessary whitespace $list = 0 if $self->{_indentation} eq ""; $nl = 0 if $self->{_indentation} eq ""; while (@_) { my $attrib = shift; my $value = $self->_encode_xml_escapes(shift); if ($list) {$element .= "\n" . $self->{_indentation} x ($level +1);} else {$element .= ' '; } $element .= $attrib; $element .= '="' . $value . '"'; } $nl = $nl ? "\n" x $nl : ""; return $element . '>'. $nl; } ############################################################################### # # _encode_xml_escapes() # # Encode standard XML escapes, namely " & < >. The apostrophe character isn't # escaped since it will only occur in double quoted strings. # sub _encode_xml_escapes { my $self = shift; my $value = $_[0]; # Print un-encoded entities for debugging return $value if $self->{_no_encoding}; for ($value) { s/&/&/g; s//>/g; s/"/"/g; # " #s/'/&pos;/g; # Not used } return $value; } ############################################################################### # # _write_xml_start_tag() # # Creates a formatted XML opening tag. Prints to the current filehandle by # default. # # Ex: # sub _write_xml_start_tag { my $self = shift; my $tag = $self->_format_tag(@_); local $\; # Make print() ignore -l on the command line. print {$self->{_filehandle}} $tag if $self->{_printed}; return $tag; } ############################################################################### # # _write_xml_directive() # # Creates a formatted XML directive. Prints to the current filehandle by # default. # # Ex: # sub _write_xml_directive { my $self = shift; my $tag = $self->_format_tag(@_); $tag =~ s[<][][?>]; local $\; # Make print() ignore -l on the command line. print {$self->{_filehandle}} $tag if $self->{_printed}; return $tag; } ############################################################################### # # _write_xml_end_tag() # # Creates the closing tag of an XML element. Prints to the current filehandle # by default. # # Ex: # sub _write_xml_end_tag { my $self = shift; my $tag = $self->_format_tag(@_); $tag =~ s[<][{_filehandle}} $tag if $self->{_printed}; return $tag; } ############################################################################### # # _write_xml_element() # # Creates a single open and closed XML element. Prints to the current # filehandle by default. # # Ex: or XML # sub _write_xml_element { my $self = shift; my $tag = $self->_format_tag(@_); $tag =~ s[>][/>]; local $\; # Make print() ignore -l on the command line. print {$self->{_filehandle}} $tag if $self->{_printed}; return $tag; } ############################################################################### # # _write_xml_content() # # Creates an encoded XML element content. Prints to the current filehandle # by default. # # Ex: Hello in Hello # sub _write_xml_content { my $self = shift; my $tag = $self->_encode_xml_escapes($_[0]); local $\; # Make print() ignore -l on the command line. print {$self->{_filehandle}} $tag if $self->{_printed}; return $tag; } ############################################################################### # # _write_xml_unencoded_content() # # Creates an un-encoded XML element content. Prints to the current filehandle # by default. Used for numerical or other data that doesn't need to be # encoded. # # Ex: 1.2345 in 1.2345 # sub _write_xml_unencoded_content { my $self = shift; my $tag = $_[0]; local $\; # Make print() ignore -l on the command line. print {$self->{_filehandle}} $tag if $self->{_printed}; return $tag; } ############################################################################### # # _set_printed() # # Turn the option to print on or off. By default this option is 1 = on. # It is mainly only turned off for testing pupropes. # sub _set_printed { my $self = shift; $self->{_printed} = $_[0]; } ############################################################################### # # _set_indentation() # # Set indentation string used to indent the output. The default is 4 spaces. # sub set_indentation { my $self = shift; $self->{_indentation} = defined $_[0] ? $_[0] : ' '; } 1; __END__ =head1 NAME XMLwriter - An abstract base class for Excel workbooks and worksheets. =head1 SYNOPSIS See the documentation for Spreadsheet::WriteExcelXML =head1 DESCRIPTION This module is used in conjunction with Spreadsheet::WriteExcelXML. =head1 AUTHOR John McNamara jmcnamara@cpan.org =head1 COPYRIGHT © MM-MMIV, John McNamara. All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.