File Coverage

blib/lib/CSS.pm
Criterion Covered Total %
statement 78 96 81.2
branch 6 18 33.3
condition 5 7 71.4
subroutine 17 19 89.4
pod 7 8 87.5
total 113 148 76.3


line stmt bran cond sub pod time code
1             package CSS;
2              
3             $VERSION = 1.09;
4              
5 8     8   151807 use strict;
  8         20  
  8         290  
6 8     8   43 use warnings;
  8         17  
  8         284  
7              
8 8     8   43 use Carp;
  8         22  
  8         742  
9 8     8   4210 use CSS::Style;
  8         23  
  8         217  
10 8     8   4315 use CSS::Selector;
  8         19  
  8         193  
11 8     8   3905 use CSS::Property;
  8         21  
  8         286  
12 8     8   4062 use CSS::Adaptor;
  8         24  
  8         337  
13              
14 8     8   9387 use Data::Dumper;
  8         70539  
  8         6475  
15              
16             sub new {
17 21     21 1 1620 my $class = shift;
18 21         75 my $self = bless {}, $class;
19              
20 21         37 my $options = shift;
21 21         114 $self->{styles} = [];
22 21   100     170 $self->{parser} = $options->{parser} || 'CSS::Parse::Lite';
23 21   100     130 $self->{adaptor} = $options->{adaptor} || 'CSS::Adaptor';
24              
25 21         74 return $self;
26             }
27              
28             sub read_file {
29 13     13 1 4989 my $self = shift;
30 13         27 my $path = shift;
31              
32 13 50       48 if (ref $path){
33 0 0       0 if (ref $path eq 'ARRAY'){
34 0         0 $self->read_file($_) for @$path;
35 0         0 return 1;
36             }
37             } else {
38 13 50       67 if ($path){
39 13         39 local *IN;
40 13 50       918 open(IN, $path) or croak "couldn't open file: $!";
41 13         1378 my $source = join '',<IN>;
42 13         304 close(IN);
43 13 50       80 $self->parse_string($source) if $source;
44 13         49185 return 1;
45             }
46             }
47 0         0 croak "only scalars and arrays accepted: $!";
48             }
49              
50             sub read_string {
51 0     0 1 0 my $self = shift;
52 0         0 my $data = shift;
53              
54 0 0       0 if (ref $data){
55 0 0       0 if (ref $data eq 'ARRAY'){
56 0         0 $self->read_string($_) for @$data;
57 0         0 return 1;
58             }
59             } else {
60 0 0       0 $self->parse_string($data) if length $data;
61             }
62             }
63              
64             sub parse_string {
65 13     13 0 27 my $self = shift;
66 13         29 my $string = shift;
67              
68             # remove comments
69 13         64 $string =~ s!/\*.*?\*\/!!g;
70 13         36 $string =~ s|<!--||g;
71 13         30 $string =~ s|-->||g;
72              
73 13     7   1253 eval "use $self->{parser}";
  7     3   4657  
  7     3   24  
  7         134  
  3         28  
  3         9  
  3         56  
  3         30  
  3         6  
  3         58  
74 13         126 my $parser_obj = new $self->{parser};
75 13         37 $parser_obj->{'parent'} = $self;
76 13         59 $parser_obj->parse_string($string);
77             }
78              
79             sub purge {
80 6     6 1 6614 my $self = shift;
81 6         25 $self->{styles} = [];
82             }
83              
84             sub set_adaptor {
85 0     0 1 0 my $self = shift;
86 0         0 my $adaptor = shift;
87              
88 0         0 $self->{adaptor} = $adaptor;
89              
90 0         0 for(@{$self->{styles}}){
  0         0  
91 0         0 $_->set_adaptor($adaptor);
92             }
93             }
94              
95             sub output {
96 3     3 1 2251 my $self = shift;
97 3   33     23 my $adaptor = shift || $self->{adaptor};
98              
99 3         5 for(@{$self->{styles}}){
  3         10  
100 3         13 $_->set_adaptor($adaptor);
101             }
102              
103 3         11 my $output = '';
104 3         7 for(@{$self->{styles}}){
  3         12  
105 3         16 $output .= "$_";
106             }
107              
108 3         10 return $output;
109             }
110              
111             sub get_style_by_selector {
112 1     1 1 546 my ($self, $sel_name) = @_;
113              
114 1         1 for my $style (@{$self->{styles}}){
  1         3  
115 2         2 for my $selector (@{$style->{selectors}}){
  2         7  
116 3 100       8 if ($selector->{name} eq $sel_name){
117 1         4 return $style;
118             }
119             }
120             }
121 0         0 return 0;
122             }
123              
124             1;
125             __END__
126              
127             =head1 NAME
128              
129             CSS - Object oriented access to Cascading Style Sheets (CSS)
130              
131             =head1 SYNOPSIS
132              
133             use CSS;
134              
135             # create a CSS object with the default options
136             my $css = CSS->new();
137              
138             # create a CSS object with a specific parser
139             my $css = CSS->new( { 'parser' => 'CSS::Parse::Lite' } );
140             my $css = CSS->new( { 'parser' => 'CSS::Parse::Heavy' } );
141             my $css = CSS->new( { 'parser' => 'CSS::Parse::Compiled' } );
142              
143             # create a CSS object with a specific adaptor
144             my $css = CSS->new( { 'adaptor' => 'CSS::Adaptor' } );
145             my $css = CSS->new( { 'adaptor' => 'CSS::Adaptor::Pretty' } );
146             my $css = CSS->new( { 'adaptor' => 'CSS::Adaptor::Debug' } );
147              
148              
149              
150             # parse some CSS from a string
151             $css->read_string( $css_data );
152             $css->read_string( ( $css_data, $more_css_data ) );
153              
154             # parse some CSS from a file
155             $css->read_file( 'my_file.css' );
156             $css->read_file( ( 'my_file.css', 'my_other_file.css' ) );
157              
158              
159              
160             # output the CSS using the current adaptor
161             print $css->output();
162              
163             # set a new adaptor and then output the CSS
164             $css->set_adaptor( 'CSS::Adaptor::Foo' );
165             print $css->output();
166              
167             # output the CSS using a tempory adaptor
168             print $css->output( 'CSS::Adaptor::Bar' );
169              
170              
171              
172             # forget about the CSS we've already parsed
173             $css->purge();
174              
175              
176             =head1 DESCRIPTION
177              
178             This module can be used, along with a CSS::Parse::* module, to parse
179             CSS data and represent it as a tree of objects. Using a CSS::Adaptor::*
180             module, the CSS data tree can then be transformed into other formats.
181              
182             =head1 NOTICE
183              
184             From version 1.00 of this module onwards, backwards compatibility is
185             broken. This is due to large changes in the way data is parsed and
186             then represented internally. Version 0.08 is still available on
187             CPAN: L<http://search.cpan.org/author/IAMCAL/CSS-0.08/>
188              
189             =head1 TREE STRUCTURE
190              
191             The CSS object is the head of the tree. It contains a list of
192             CSS::Style objects which each represent a CSS ruleset. Each of
193             these objects contains a list of selectors and properties. Each
194             selector is stored as a CSS::Selector object. Each property
195             object is stored as a CSS::Property object and contains a list
196             of values. These values are stored as CSS::Value objects.
197              
198             foo, bar {
199             baz: fop;
200             woo: yay houpla;
201             }
202              
203             The above example would be represented as a single CSS::Style object.
204             That object would then have two CSS::Selector objects representing
205             'foo' and 'bar'. It would also have two CSS::Property objects
206             representing 'baz' and 'woo'. The 'baz' object then has a single child
207             CSS::Value object for 'fop', whilst the 'woo' object has two
208             child objects for 'yay' and 'houpla'.
209              
210             =head1 METHODS
211              
212             =head2 CONSTRUCTOR
213              
214             =over 4
215              
216             =item C<new()> or C<new( { ..options.. } )>
217              
218             An optional hash can contain arguments:
219              
220             parser module to use as the CSS parser
221             adaptor adaptor to use for output
222              
223             =back
224              
225             =head2 ACCESSORS
226              
227             =over 4
228              
229             =item C<read_file( $filename )> or C<read_file( @filenames )>
230              
231             Read one or mores files and parse the CSS within them.
232              
233              
234             =item C<read_string( $scalar )> or C<read_string( @strings )>
235              
236             Read one or more strings and parse the CSS within them.
237              
238              
239             =item C<output()> or C<output( 'CSS::Adaptor::Foo' )>
240              
241             Return a string representation of the CSS tree, using either the
242             current adaptor or the specified one.
243              
244              
245             =item C<set_adaptor( 'CSS::Adaptor::Bar' )>
246              
247             Set the current adaptor for the CSS tree.
248              
249              
250             =item C<purge()>
251              
252             Forget all the objects in the CSS tree;
253              
254              
255             =item C<get_style_by_selector( 'selector_name' )>
256              
257             Returns the first CSS::Style object with the specified selector
258             name attached. Returns zero on failure.
259              
260              
261             =back
262              
263             =head1 AUTHORS
264              
265             Copyright (C) 2001-2002, Allen Day <allenday@ucla.edu>
266              
267             Copyright (C) 2003-2004, Cal Henderson <cal@iamcal.com>
268              
269             =head1 SEE ALSO
270              
271             L<CSS::Style>, L<CSS::Selector>, L<CSS::Property>, L<CSS::Value>,
272             L<CSS::Parse>, L<CSS::Parse::Lite>, L<CSS::Parse::Heavy>,
273             L<CSS::Parse::Compiled>, L<CSS::Parse::PRDGrammar>, L<CSS::Adaptor>,
274             L<CSS::Adaptor::Pretty>, L<CSS::Adaptor::Debug>, perl(1)
275              
276             =cut