#!/usr/local/bin/perl -w # POD docs at end use strict; use Data::Stag qw(:all); use Getopt::Long; use FileHandle; my $exec; my $codefile; my $parser = ''; my $errhandler = ""; my $errf; my $writer = ''; my %trap = (); my $datafmt; my $module; my @units; GetOptions("codefile|c=s"=>\$codefile, "sub|s=s"=>\$exec, "trap|t=s%"=>\%trap, "parser|format|p=s" => \$parser, "errhandler=s" => \$errhandler, "errf|e=s" => \$errf, "writer|w=s"=>\$writer, "data|d=s"=>\$datafmt, "module|m=s"=>\$module, "units|u=s@"=>\@units, "help|h"=>sub {system("perldoc $0");exit 0}, ); if (!$codefile && !$exec && !$module) { $codefile = shift @ARGV if (@ARGV > 1); die "you must supply -c or -m or -s, or provide codefile" unless $codefile; } my @files = @ARGV; $errhandler = Data::Stag->getformathandler($errhandler || 'xml'); if ($errf) { $errhandler->file($errf); } else { $errhandler->fh(\*STDERR); } my $catch = {}; no strict; if ($exec) { $catch = eval $exec; if ($@) { die $@; } if (ref($catch) ne 'HASH') { print STDERR "exec \"$exec\" is not a hash"; exit 1; } } if ($codefile) { $catch = do "$codefile"; if ($@) { print STDERR "\n\nstag-handle error:\n"; print STDERR "There was an error with the codefile \"$codefile\":\n\n"; die $@; } if (ref($catch) ne 'HASH') { print STDERR "codefile \"$codefile\" does not return a hash"; exit 1; } } if (%trap) { # # die Dumper \%trap; %$catch = (%$catch, %trap); } use strict; my @events; my $inner_handler; if ($module) { $inner_handler = Data::Stag->makehandler($module); } else { my $meth = $exec ? $exec : $codefile; if (!%$catch) { die "method \"$meth\" did not return handler"; } if (!ref($catch) || ref($catch) ne "HASH") { die("$meth must return hashref"); } $inner_handler = Data::Stag->makehandler(%$catch); @events = keys %$catch; } if (@units) { @events = @units; } $inner_handler->errhandler($errhandler); my $h = Data::Stag->chainhandlers([@events], $inner_handler, $writer); while (my $fn = shift @files) { my $fh; if (!$fn || $fn eq '-') { $fh = \*STDIN; $fn = ''; } else { $fh = FileHandle->new($fn) || die "Cannot open file: $fn"; } my $p = Data::Stag->parser(-file=>$fn, -format=>$parser, -errhandler=>$errhandler); $p->handler($h); $p->parse_fh($fh); if ($datafmt) { print $inner_handler->stag->$datafmt(); } } __END__ =head1 NAME stag-handle.pl - streams a stag file through a handler into a writer =head1 SYNOPSIS stag-handle.pl -w itext -c my-handler.pl myfile.xml > processed.itext stag-handle.pl -w itext -p My::Parser -m My::Handler myfile.xml > processed.itext =head1 DESCRIPTION will take a Stag compatible format (xml, sxpr or itext), turn the data into an event stream passing it through my-handler.pl =over ARGUMENTS =item -help|h shows this document =item -module|m PERLMODULE A module that is used to transform the input events the module should inherit from L =item -unit|u NODE_NAME (you should always use this option if you specify -m) this is the unit that gets passed to the handler/transformer. this will get set automatically if you use the the -c, -s or -t options multiple units can be set -u foo -u bar -u boz =item -writer|w WRITER writer for final transformed tree; can be xml, sxpr or itext =item -module|m MODULE perl modules for handling events =item -codefile|c FILE a file containing a perlhashref containing event handlers - see below =item -sub|s PERL a perl hashref containing handlers =item -trap|t ELEMENT=SUB =back =head1 EXAMPLES unix> cat my-handler.pl { person => sub { my ($self, $person) = @_; $person->set_fullname($person->get_firstname . ' ' . $person->get_lastname); $person; }, address => sub { my ($self, $address) = @_; # remove addresses altogether from processed file return; }, } =cut