File Coverage

blib/lib/PYX/GraphViz.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package PYX::GraphViz;
2              
3             # Pragmas.
4 4     4   35230 use strict;
  4         6  
  4         149  
5 4     4   16 use warnings;
  4         7  
  4         135  
6              
7             # Modules.
8 4     4   2024 use Class::Utils qw(set_params);
  4         35595  
  4         65  
9 4     4   215 use Error::Pure qw(err);
  4         7  
  4         115  
10 4     4   131308 use GraphViz;
  0            
  0            
11             use PYX::Parser;
12              
13             # Version.
14             our $VERSION = 0.02;
15              
16             # Global variables.
17             use vars qw($num $object $stack);
18              
19             # Constructor.
20             sub new {
21             my ($class, @params) = @_;
22              
23             # Object.
24             my $self = bless {}, $class;
25              
26             # Colors.
27             $self->{'colors'} = {
28             'a' => 'blue',
29             'blockquote' => 'orange',
30             'br' => 'orange',
31             'div' => 'green',
32             'form' => 'yellow',
33             'html' => 'black',
34             'img' => 'violet',
35             'input' => 'yellow',
36             'option' => 'yellow',
37             'p' => 'orange',
38             'select' => 'yellow',
39             'table' => 'red',
40             'td' => 'red',
41             'textarea' => 'yellow',
42             'tr' => 'red',
43             '*' => 'grey',
44             };
45              
46             # Layout.
47             $self->{'layout'} = 'neato';
48              
49             # Height and width.
50             $self->{'height'} = 10;
51             $self->{'width'} = 10;
52              
53             # Node height.
54             $self->{'node_height'} = 0.3;
55              
56             # Output handler.
57             $self->{'output_handler'} = \*STDOUT;
58              
59             # Process params.
60             set_params($self, @params);
61              
62             # PYX::Parser object.
63             $self->{'_pyx_parser'} = PYX::Parser->new(
64             'output_handler' => $self->{'output_handler'},
65              
66             # Handlers.
67             'end_tag' => \&_end_tag,
68             'final' => \&_final,
69             'start_tag' => \&_start_tag,
70             );
71              
72             # Check to '*' color.
73             if (! exists $self->{'colors'}->{'*'}) {
74             err "Bad color define for '*' tags.";
75             }
76              
77             # GraphViz object.
78             $self->{'_graphviz'} = GraphViz->new(
79             'layout' => $self->{'layout'},
80             'overlap' => 'scale',
81             'height' => $self->{'height'},
82             'width' => $self->{'width'},
83             );
84              
85             # Object.
86             $object = $self;
87              
88             # Number iterator.
89             $num = 0;
90              
91             # Stack.
92             $stack = [];
93              
94             # Object.
95             return $self;
96             }
97              
98             # Parse pyx text or array of pyx text.
99             sub parse {
100             my ($self, $pyx, $out) = @_;
101             $self->{'_pyx_parser'}->parse($pyx, $out);
102             return;
103             }
104              
105             # Parse file with pyx text.
106             sub parse_file {
107             my ($self, $file, $out) = @_;
108             $self->{'_pyx_parser'}->parse_file($file, $out);
109             return;
110             }
111              
112             # Parse from handler.
113             sub parse_handler {
114             my ($self, $input_file_handler, $out) = @_;
115             $self->{'_pyx_parser'}->parse_handler($input_file_handler, $out);
116             return;
117             }
118              
119             # Process tag.
120             sub _start_tag {
121             my ($pyx_parser_obj, $tag) = @_;
122             $num++;
123             my $color;
124             if (exists $object->{'colors'}->{$tag}) {
125             $color = $object->{'colors'}->{$tag};
126             } else {
127             $color = $object->{'colors'}->{'*'};
128             }
129             $object->{'_graphviz'}->add_node($num,
130             'color' => $color,
131             'height' => $object->{'node_height'},
132             'shape' => 'point'
133             );
134             if (@{$stack}) {
135             $object->{'_graphviz'}->add_edge(
136             $num => $stack->[-1]->[1],
137             'arrowhead' => 'none',
138             'weight' => 2,
139             );
140             }
141             push @{$stack}, [$tag, $num];
142             return;
143             }
144              
145             # Process tag.
146             sub _end_tag {
147             my ($pyx_parser_obj, $tag) = @_;
148             if ($stack->[-1]->[0] eq $tag) {
149             pop @{$stack};
150             }
151             return;
152             }
153              
154             # Final.
155             sub _final {
156             my $pyx_parser_obj = shift;
157             my $out = $pyx_parser_obj->{'output_handler'};
158             $object->{'_graphviz'}->as_png($out);
159             return;
160             }
161              
162             1;
163              
164             __END__