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<new>
my $obj = PYX::SGML::Tags->new(%parameters);
Constructor.
Returns instance of class.
=over 8
=item * C<input_encoding>
Input encoding for parse_file() and parse_handler() usage.
Default value is 'utf-8'.
=item * C<input_tags_item_callback>
Input 'Tags' item callback.
This callback is for Tags::Output::* constructor parameter 'input_tags_item_callback'.
Default value is undef.
=item * C<output_encoding>
Output encoding.
Default value is 'utf-8'.
=item * C<tags>
Tags object.
Can be any of Tags::Output::* objects.
Default value is C<Tags::Output::Raw->new('output_handler' => \*STDOUT)>.
It's required.
=back
=head2 C<parse>
$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<parse_file>
$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<parse_handler>
$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<finalize>
$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:
# <element>data</element>
=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:
# <element>data</element>
=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 ]
# <element>data</element>
=head1 DEPENDENCIES
L<Class::Utils>,
L<Error::Pure>,
L<PYX::Parser>,
L<PYX::Utils>,
L<Tags::Output::Raw>.
=head1 SEE ALSO
=over
=item L<Task::PYX>
Install the PYX modules.
=back
=head1 REPOSITORY
L<https://github.com/michal-josef-spacek/PYX-SGML-Tags>
=head1 AUTHOR
Michal Josef Špaček L<mailto:skim@cpan.org>
L<http://skim.cz>
=head1 LICENSE AND COPYRIGHT
© 2011-2021 Michal Josef Špaček
BSD 2-Clause License
=head1 VERSION
0.08
=cut