File Coverage

blib/lib/Graph/Template.pm
Criterion Covered Total %
statement 18 20 90.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 25 27 92.5


line stmt bran cond sub pod time code
1             package Graph::Template;
2              
3 1     1   29523 use strict;
  1         3  
  1         49  
4              
5             BEGIN {
6 1     1   569 use Graph::Template::Base;
  1         3  
  1         30  
7 1     1   5 use vars qw ($VERSION @ISA);
  1         2  
  1         56  
8              
9 1     1   3 $VERSION = '0.05';
10 1         34 @ISA = qw (Graph::Template::Base);
11             }
12              
13 1     1   5 use File::Basename;
  1         1  
  1         105  
14 1     1   810 use IO::File;
  1         10239  
  1         139  
15 1     1   1643 use XML::Parser;
  0            
  0            
16              
17             sub new
18             {
19             my $class = shift;
20             my $self = $class->SUPER::new(@_);
21              
22             $self->parse_xml($self->{FILENAME})
23             if defined $self->{FILENAME};
24              
25             return $self;
26             }
27              
28             sub param
29             {
30             my $self = shift;
31              
32             # Allow an arbitrary number of hashrefs, so long as they're the first things
33             # into param(). Put each one onto the end, de-referenced.
34             push @_, %{shift @_} while UNIVERSAL::isa($_[0], 'HASH');
35              
36             (@_ % 2)
37             && die __PACKAGE__, "->param() : Odd number of parameters to param()\n";
38              
39             my %params = @_;
40             $params{uc $_} = delete $params{$_} for keys %params;
41             @{$self->{PARAM_MAP}}{keys %params} = @params{keys %params};
42              
43             return 1;
44             }
45              
46             sub write_file
47             {
48             my $self = shift;
49             my ($filename) = @_;
50              
51             my ($graph, $method) = $self->_prepare_output;
52              
53             open IMG, ">$filename"
54             or die "Cannot open '$filename' for writing: $!\n";
55             binmode IMG;
56             print IMG $graph->$method;
57             close IMG;
58             }
59              
60             sub output
61             {
62             my $self = shift;
63              
64             my ($graph, $method) = $self->_prepare_output;
65              
66             binmode STDOUT;
67             $graph->$method;
68             }
69              
70             sub parse
71             {
72             my $self = shift;
73              
74             $self->parse_xml(@_);
75             }
76              
77             sub parse_xml
78             {
79             my $self = shift;
80             my ($filename) = @_;
81              
82             my ($fname, $dirname) = fileparse($filename);
83              
84             my @stack;
85             my $parser = XML::Parser->new(
86             Base => $dirname,
87             Handlers => {
88             Start => sub {
89             shift;
90              
91             my $name = uc shift;
92              
93             my $node = Graph::Template::Factory->create_node($name, @_);
94             die "'$name' (@_) didn't make a node!\n" unless defined $node;
95              
96             if ($name eq 'GRAPH')
97             {
98             push @{$self->{GRAPHS}}, $node;
99             }
100             elsif ($name eq 'VAR')
101             {
102             return unless @stack;
103              
104             if (exists $stack[-1]{TXTOBJ} &&
105             $stack[-1]{TXTOBJ}->isa('TEXTOBJECT'))
106             {
107             push @{$stack[-1]{TXTOBJ}{STACK}}, $node;
108             }
109              
110             }
111             else
112             {
113             push @{$stack[-1]{ELEMENTS}}, $node
114             if @stack;
115             }
116             push @stack, $node;
117             },
118             Char => sub {
119             shift;
120             return unless @stack;
121              
122             my $parent = $stack[-1];
123              
124             if (
125             exists $parent->{TXTOBJ}
126             &&
127             $parent->{TXTOBJ}->isa('TEXTOBJECT')
128             ) {
129             push @{$parent->{TXTOBJ}{STACK}}, @_;
130             }
131             },
132             End => sub {
133             shift;
134             return unless @stack;
135              
136             pop @stack if $stack[-1]->isa(uc $_[0]);
137             },
138             },
139             );
140              
141             {
142             my $fh = IO::File->new($filename)
143             || die "Cannot open '$filename' for reading: $!\n";
144              
145             $parser->parse(do { local $/ = undef; <$fh> });
146              
147             $fh->close;
148             }
149              
150             return 1;
151             }
152              
153             sub _prepare_output
154             {
155             my $self = shift;
156             my ($graph) = @_;
157              
158             my $context = Graph::Template::Factory->create(
159             'CONTEXT',
160              
161             PARAM_MAP => [ $self->{PARAM_MAP} ],
162             );
163              
164             foreach my $graph (@{$self->{GRAPHS}})
165             {
166             foreach my $method (qw( enter_scope render exit_scope ))
167             {
168             $graph->$method($context);
169             }
170             }
171              
172             return ($context->plotted_graph, $context->format);
173             }
174              
175             sub register { shift; Graph::Template::Factory::register(@_) }
176              
177             1;
178             __END__