package Apache2::ASP::Parser;
use strict;
use warnings 'all';
use Data::Dumper;
#==============================================================================
sub parse_file
{
my ($s, $file) = @_;
no warnings 'uninitialized';
open my $ifh, '<', $file
or die "Cannot open file '$file': $!";
local $/;
my $txt = <$ifh>;
close($ifh);
return $s->parse_string( $txt );
}# end parse_file()
#==============================================================================
sub parse_string
{
my ($class, $txt) = @_;
# Look for ... elements:
while(
$txt =~ m@
(<(([a-z]+?[a-z0-9_]*\:[a-z0-9_\:]+)\s*(.*?))>(.*?)\3\s*>)
@xi #@ Make Gedit Happy
) {
my $tagname = $3;
my $argstr = $4;
my $fulltag = $1;
my $innerHTML = $5;
$class->_render_tag(
\$txt, $tagname, $argstr, $fulltag, $innerHTML
);
}# end while()
# Look for elements:
while(
$txt =~ m@
(<(([a-z]+?[a-z0-9_]*\:[a-z0-9_\:]+)\s*(.*?))/>)
@xi #@ Make Gedit Happy
)
{
my $tagname = $3;
my $argstr = $4;
my $fulltag = $1;
$class->_render_tag(
\$txt, $tagname, $argstr, $fulltag
);
}# end while()
$txt = $class->_parse_asp_tags( $txt );
}# end parse_string()
#==============================================================================
sub _render_tag
{
my ($class, $aspstr, $tagname, $argstr, $fulltag, $innerHTML) = @_;
no strict 'refs';
(my $pkg = $tagname) =~ s/:/::/g;
(my $pkgfile = "$pkg.pm") =~ s/::/\//g;
eval { require $pkgfile } unless @{"$pkg\::ISA"};
no warnings 'uninitialized';
$innerHTML =~ s/\~/\\~/g;
if( @{"$pkg\::ISA"} )
{
(my $args = Dumper($class->_parse_tag_args( $argstr ))) =~ s/^\$VAR1\s+\=\s+//;
$args =~ s/;$//;
$$aspstr =~ s@
\Q$fulltag\E
@~);__PACKAGE__->_load_tag_class('$pkg');\$Response->Write($pkg\->new->render( $args, q~$innerHTML~ ));\$Response->Write(q~@xi; #@ Make Gedit Happy
}
elsif( defined *{"$pkg"} )
{
my @parts = split /::/, $pkg;
pop(@parts);
my $pkg_class = join '::', @parts;
(my $args = Dumper($class->_parse_tag_args( $argstr ))) =~ s/^\$VAR1\s+\=\s+//;
$args =~ s/;$//;
$$aspstr =~ s@
\Q$fulltag\E
@~);__PACKAGE__->_load_tag_class('$pkg_class');\$Response->Write(\&$pkg( $args, q~$innerHTML~ ));\$Response->Write(q~@xi; #@ Make Gedit Happy
}
else
{
die "Cannot load tag '$tagname': $@";
}# end if()
}# end _render_tag()
#==============================================================================
sub _parse_tag_args
{
my ($s, $str) = @_;
my $attr = { };
while( $str =~ m@([^\s\=\"\']+)(\s*=\s*(?:(")(.*?)"|(')(.*?)'|([^'"\s=]+)['"]*))?@sg ) #@
{
my $key = $1;
my $test = $2;
my $val = ( $3 ? $4 : ( $5 ? $6 : $7 ));
my $lckey = lc($key);
if( $test )
{
$key =~ tr/A-Z/a-z/;
$attr->{$lckey} = $val;
}
else
{
$attr->{$lckey} = $key;
}# end if()
}# end while()
return $attr;
}# end _parse_tag_args()
#==============================================================================
sub _parse_asp_tags
{
my ($class, $txt) = @_;
$txt = '$Response->Write(q~' . $txt . '~);';
$txt =~ s@
<\%([^\=].*?)\%>
@~);$1;\$Response->Write(q~@sgx;
$txt =~ s@
<%=(.*?)%>
@~);\$Response->Write($1);\$Response->Write(q~@sgx;
$txt =~ s@\$Response\-\>End(?:\(?[\s.]*?\)?);@return;@g;
$txt =~ s@\$Response\-\>Redirect\(@return \$Response\->Redirect\(@g;
$txt =~ s@\$Response\-\>Write\(q\~(.*?)\~\);@
'$Response->Write(q~' . _fix_tilde($1) . '~);'
@sxge;
return $txt;
}# end _parse_asp_tags()
#==============================================================================
sub _fix_tilde
{
my $str = shift;
$str =~ s/~/_____TILDE_____/g;
return $str;
}# end _fix_tilde()
1;# return true:
__END__
=pod
=head1 NAME
Apache2::ASP::Parser - ASP -> Perl parsing engine
=head1 SYNOPSIS
my $parsed_file = Apache2::ASP::Parser->parse_file( $asp_filename );
my $parsed_str = Apache2::ASP::Parser->parse_string( $asp_string );
=head1 DESCRIPTION
Converts ASP code like:
<%
$Response->Write("Hello, World!");
$Response->End;
%>
Into Perl code like:
$Response->Write(q~~);
$Response->Write("Hello, World!");
return;
;$Response->Write(q~
~);
=head1 METHODS
=head2 parse_file( $path_to_file )
Returns the contents of that file, parsed into ASP Perl.
=head2 parse_string( $str )
Returns C<$str>, parsed into ASP Perl.
=head1 BUGS
It's possible that some bugs have found their way into this release.
Use RT L to submit bug reports.
=head1 HOMEPAGE
Please visit the Apache2::ASP homepage at L to see examples
of Apache2::ASP in action.
=head1 AUTHOR
John Drago L
=head1 COPYRIGHT AND LICENSE
Copyright 2007 John Drago, All rights reserved.
This software is free software. It may be used and distributed under the
same terms as Perl itself.
=cut