use warnings;
use strict;
sub escape_ents {
local $_ = shift;
s/&/&/g;
s/</g;
s/>/>/g;
s/"/"/g; # "
s/'/'/g;
return $_;
}
sub stringify_attribs {
return join '',
map{
' '.escape_ents( $_ ).'="'.escape_ents( $_[0]{$_} ).'"'
} sort keys %{$_[0]};
}
####
sub XML_elem {
my $tag = shift;
my @results; # return value
my $attribs = shift @_ if( ref( $_[0] ) eq 'HASH' );
push @results, "<${tag}" . stringify_attribs( $attribs ) . ">";
if( @_ == 0 ) { # handle an empty element
$results[0] =~ s|>$| />|;
return @results;
}
foreach my $arg ( @_ ) {
if( ref( $arg ) eq 'CODE' ) {
push @results, map{ " $_" } $arg->(); # <--- ???
} else {
push @results, ' ' . escape_ents( $arg )
}
}
push @results, "<\\${tag}>";
return @results;
}
##
##
print "\n == code fragment 1 ============================================= \n";
print join "\n",
XML_elem( 'root', { ID => 0 },
XML_elem( 'branch',
XML_elem( 'sub_branch', { foo => 2 },
'some contents & entities, "<>"'
),
'other contents',
),
'root stuff',
);
##
##
__END__
# ml (Make Lazy) takes a reference to a subroutine as it's 1st arg. All
# remaining args are saved and used as arguments for the subroutine when
# the results of execution are desired. returns a subroutine that behaves
# almost exactly as if the subroutine had been called when ml was called.
sub ml {
my $sub = shift;
my @args = @_;
return sub {
return $sub->( @args );
};
}
##
##
print "\n == code fragment 2 ============================================= \n";
print join "\n",
XML_elem( 'root', { ID => 0 },
ml( \&XML_elem, 'branch',
ml( \&XML_elem, 'sub_branch', { foo => 2 },
'some contents & entities, "<>"'
),
'other contents',
),
'root stuff',
);
##
##
__END__
# ca4ml (Curry Arguments for ML)
sub ca4ml {
my $sub = shift;
my $tag = shift;
return sub {
my @args = @_;
return ml( $sub, $tag, @args );
}
}
print "\n == code fragment 3 ============================================= \n";
my $root = ca4ml( \&XML_elem, 'root' );
my $branch = ca4ml( \&XML_elem, 'branch' );
my $sub_branch = ca4ml( \&XML_elem, 'sub_branch' );
print join "\n",
$root->( { ID => 0 },
$branch->(
$sub_branch->( { foo => 2 },
'some contents & entities "<>"'
),
'other contents',
),
'root stuff',
)->();
##
##
__END__
sub make_func {
my $tag = shift;
return sub {
my @args = @_;
return ml( \&XML_elem, $tag, @args );
}
}
print "\n == code fragment 4 ============================================= \n";
$root = make_func( 'root' );
$branch = make_func( 'branch' );
$sub_branch = make_func( 'sub_branch' );
print join "\n",
$root->( { ID => 0 },
$branch->(
$sub_branch->( { foo => 2 },
'some contents & entities "<>"'
),
'other contents',
),
'root stuff',
)->();
;
__END__