package PYX::SGML::Tags; use strict; use warnings; use Class::Utils qw(set_params); use Error::Pure qw(err); use PYX::Parser; use PYX::Utils; use Tags::Output::Raw; our $VERSION = 0.08; # Constructor. sub new { my ($class, @params) = @_; my $self = bless {}, $class; # Input encoding. $self->{'input_encoding'} = 'utf-8'; # Input 'Tags' item callback. $self->{'input_tags_item_callback'} = undef; # Output encoding. $self->{'output_encoding'} = 'utf-8'; # Tags object. $self->{'tags'} = undef; # Process params. set_params($self, @params); if (! defined $self->{'tags'}) { $self->{'tags'} = Tags::Output::Raw->new( 'input_tags_item_callback' => $self->{'input_tags_item_callback'}, 'output_encoding' => $self->{'output_encoding'}, 'output_handler' => \*STDOUT, ); } # Check for Tags::Output object. if (! $self->{'tags'}->isa('Tags::Output')) { err "Bad 'Tags::Output::*' object."; } # PYX::Parser object. $self->{'pyx_parser'} = PYX::Parser->new( 'callbacks' => { 'attribute' => \&_attribute, 'comment' => \&_comment, 'data' => \&_data, 'end_element' => \&_end_element, 'instruction' => \&_instruction, 'start_element' => \&_start_element, }, 'input_encoding' => $self->{'input_encoding'}, 'non_parser_options' => { 'tags' => $self->{'tags'}, }, ); # Object. return $self; } # Parse pyx text or array of pyx text. sub parse { my ($self, $pyx, $out) = @_; $self->{'pyx_parser'}->parse($pyx, $out); $self->{'tags'}->flush; return; } # Parse file with pyx text. sub parse_file { my ($self, $file, $out) = @_; $self->{'pyx_parser'}->parse_file($file, $out); $self->{'tags'}->flush; return; } # Parse from handler. sub parse_handler { my ($self, $input_file_handler, $out) = @_; $self->{'pyx_parser'}->parse_handler($input_file_handler, $out); $self->{'tags'}->flush; return; } sub finalize { my $self = shift; $self->{'tags'}->finalize; return; } # Process start of element. sub _start_element { my ($self, $elem) = @_; my $tags = $self->{'non_parser_options'}->{'tags'}; $tags->put(['b', $elem]); return; } # Process end of element. sub _end_element { my ($self, $elem) = @_; my $tags = $self->{'non_parser_options'}->{'tags'}; $tags->put(['e', $elem]); return; } # Process data. sub _data { my ($self, $data) = @_; my $tags = $self->{'non_parser_options'}->{'tags'}; $tags->put(['d', PYX::Utils::encode($data)]); return; } # Process attribute. sub _attribute { my ($self, $attr, $value) = @_; my $tags = $self->{'non_parser_options'}->{'tags'}; $tags->put(['a', $attr, $value]); return; } # Process instruction tag. sub _instruction { my ($self, $target, $code) = @_; my $tags = $self->{'non_parser_options'}->{'tags'}; $tags->put(['i', $target, $code]); return; } # Process comments. sub _comment { my ($self, $comment) = @_; my $tags = $self->{'non_parser_options'}->{'tags'}; $tags->put(['c', PYX::Utils::encode($comment)]); return; } 1; __END__ =pod =encoding utf8 =head1 NAME PYX::SGML::Tags - Processing PYX data or file and write as SGML via Tags. =head1 SYNOPSIS use PYX::SGML::Tags; my $obj = PYX::SGML::Tags->new(%parameters); $obj->parse($pyx, $out); $obj->parse_file($input_file, $out); $obj->parse_handle($input_file_handler, $out); $obj->finalize; =head1 METHODS =head2 C my $obj = PYX::SGML::Tags->new(%parameters); Constructor. Returns instance of class. =over 8 =item * C Input encoding for parse_file() and parse_handler() usage. Default value is 'utf-8'. =item * C Input 'Tags' item callback. This callback is for Tags::Output::* constructor parameter 'input_tags_item_callback'. Default value is undef. =item * C Output encoding. Default value is 'utf-8'. =item * C Tags object. Can be any of Tags::Output::* objects. Default value is Cnew('output_handler' => \*STDOUT)>. It's required. =back =head2 C $obj->parse($pyx, $out); Parse PYX text or array of PYX text. Output is serialization to SGML by Tags::Output::* module. If C<$out> not present, use 'output_handler'. Returns undef. =head2 C $obj->parse_file($input_file, $out); Parse file with PYX data. C<$input_file> file is decoded by 'input_encoding'. Output is serialization to SGML. If C<$out> not present, use 'output_handler'. Returns undef. =head2 C $obj->parse_handle($input_file_handler, $out); Parse PYX handler. C<$input_file_handler> handler is decoded by 'input_encoding'. Output is serialization to SGML. If C<$out> not present, use 'output_handler'. Returns undef. =head2 C $obj->finalize; Finalize opened tags, if exists. Returns undef. =head1 ERRORS new(): Bad 'Tags::Output::*' object. From Class::Utils::set_params(): Unknown parameter '%s'. parse(): From PYX::Parser::parse(): Bad PYX line '%s'. From Tags::Output::Raw::flush(): Cannot write to output handler. parse_file(): From PYX::Parser::parse_file(): Bad PYX line '%s'. No input handler. From Tags::Output::Raw::flush(): Cannot write to output handler. parse_handler(): From PYX::Parser::parse_handler(): Bad PYX line '%s'. No input handler. From Tags::Output::Raw::flush(): Cannot write to output handler. =head1 EXAMPLE1 use strict; use warnings; use PYX::SGML::Tags; # Input. my $pyx = <<'END'; (element -data )element END # Object. my $obj = PYX::SGML::Tags->new; # Process. $obj->parse($pyx); print "\n"; # Output: # data =head1 EXAMPLE2 use strict; use warnings; use PYX::SGML::Tags; use Tags::Output::Indent; # Input. my $pyx = <<'END'; (element -data )element END # Object. my $obj = PYX::SGML::Tags->new( 'tags' => Tags::Output::Indent->new( 'output_handler' => \*STDOUT, ), ); # Process. $obj->parse($pyx); print "\n"; # Output: # data =head1 EXAMPLE3 use strict; use warnings; use PYX::SGML::Tags; use Tags::Output::Indent; # Input. my $pyx = <<'END'; (element -data )element END # Object. my $obj = PYX::SGML::Tags->new( 'input_tags_item_callback' => sub { my $tags_ar = shift; print '[ '.$tags_ar->[0].' ]'."\n"; return; }, ); # Process. $obj->parse($pyx); print "\n"; # Output: # [ b ] # [ d ] # [ e ] # data =head1 DEPENDENCIES L, L, L, L, L. =head1 SEE ALSO =over =item L Install the PYX modules. =back =head1 REPOSITORY L =head1 AUTHOR Michal Josef Špaček L L =head1 LICENSE AND COPYRIGHT © 2011-2021 Michal Josef Špaček BSD 2-Clause License =head1 VERSION 0.08 =cut