File Coverage

blib/lib/CSS/Object/Format.pm
Criterion Covered Total %
statement 92 104 88.4
branch 28 60 46.6
condition 1 2 50.0
subroutine 28 33 84.8
pod 19 20 95.0
total 168 219 76.7


line stmt bran cond sub pod time code
1             ##----------------------------------------------------------------------------
2             ## CSS Object Oriented - ~/lib/CSS/Object/Format.pm
3             ## Version v0.1.0
4             ## Copyright(c) 2020 DEGUEST Pte. Ltd.
5             ## Author: Jacques Deguest <@sitael.local>
6             ## Created 2020/06/21
7             ## Modified 2020/06/21
8             ##
9             ##----------------------------------------------------------------------------
10             package CSS::Object::Format;
11             BEGIN
12             {
13 6     6   48 use strict;
  6         27  
  6         204  
14 6     6   31 use warnings;
  6         12  
  6         180  
15 6     6   30 use parent qw( Module::Generic );
  6         15  
  6         34  
16 6     6   352 use Devel::Confess;
  6         14  
  6         48  
17 6     6   9236 our $VERSION = 'v0.1.0';
18             };
19              
20             sub init
21             {
22 57     57 1 48014 my $self = shift( @_ );
23 57         452 $self->{new_line} = "\n";
24 57         149 $self->{open_brace_on_new_line} = 1;
25 57         143 $self->{close_brace_on_new_line} = 1;
26 57         174 $self->{open_brace_and_new_line} = 1;
27 57         158 $self->{indent} = '';
28 57         150 $self->{property_separator} = "\n";
29 57         197 $self->{_init_strict_use_sub} = 1;
30 57         430 $self->SUPER::init( @_ );
31 57         4181 $self->{_params} = [qw(
32             close_brace_on_new_line
33             indent
34             new_line
35             open_brace_and_new_line
36             open_brace_on_new_line
37             property_separator
38             )];
39 57         177 return( $self );
40             }
41              
42 18     18 1 309 sub backup_parameters { return( shift->clone ); }
43              
44 31     31 0 836 sub class { return( ref( $_[0] ) ); }
45              
46 409     409 1 12419 sub close_brace_on_new_line { return( shift->_set_get_boolean( 'close_brace_on_new_line', @_ ) ); }
47              
48             sub comment_as_string
49             {
50 47     47 1 1055 my( $self, $elem ) = @_;
51             # no overloading;
52 47 50       164 return( $self->error( "No comment object was provided." ) ) if( !defined( $elem ) );
53 47 50       163 return( $self->error( "Comment object provied is not a CSS::Object::Comment object." ) ) if( !$self->_is_a( $elem, 'CSS::Object::Comment' ) );
54 47         1100 return( '/* ' . $elem->values->join( "\n" )->scalar . ' */' );
55             }
56              
57             sub copy_parameters_from
58             {
59 22     22 1 367 my $self = shift( @_ );
60 22   50     70 my $fmt = shift( @_ ) || return( $self->error( "No formatter object was provided to copy the parameters from." ) );
61 22 50       71 return( $self->error( "Formatter object provided is actually not a formatter object." ) ) if( !$self->_is_a( $fmt, 'CSS::Object::Format' ) );
62             # my( $p, $f, $l ) = caller();
63             # $self->message( 3, "copy_parameters_from called from package $p at line $l in file $f to set indent from '", $self->indent->scalar, "' to '", $fmt->indent->scalar, "'." );
64 22         375 my $ok_params = $self->{_params};
65 22         49 for( @$ok_params )
66             {
67 132 50       9194 $self->$_( $fmt->$_ ) if( $fmt->can( $_ ) );
68             }
69 22         3178 return( $self );
70             }
71              
72             sub elements_as_string
73             {
74 331     331 1 14401 my( $self, $elems ) = @_;
75             # no overloading;
76 331 50       1133 return( $self->error( "No elements array was provided." ) ) if( !defined( $elems ) );
77 331 50       973 return( $self->error( "Elements provided is not an array object." ) ) if( !$self->_is_a( $elems, 'Module::Generic::Array' ) );
78 331         5753 my $result = Module::Generic::Array->new;
79 331         3246 my $nl = $self->new_line->scalar;
80 331         16893 my $prop_sep = $self->property_separator->scalar;
81             # $self->message( 3, "Property separator is set to \"$prop_sep\"." );
82             ## $prop_sep .= $self->indent->scalar;
83             $elems->foreach(sub
84             {
85             # $self->message( 3, "Stringifying element object of class \"" . $_->class . "\"." );
86 279 100   279   41341 $result->push( $_->format->indent->scalar . $_->as_string . ( $_->isa( 'CSS::Object::Comment' ) ? '' : ';' ) );
87 331         16609 });
88 331         72650 return( $result->join( $prop_sep )->scalar );
89             }
90              
91             ## sub indent { return( shift->_set_get_scalar_as_object( 'indent', @_ ) ); }
92             sub indent
93             {
94 1073     1073 1 19420 my $self = shift( @_ );
95 1073 100       2928 if( @_ )
96             {
97 161         343 my $val = shift( @_ );
98             # my( $p, $f, $l ) = caller();
99             # $self->message( 3, "Format called from package $p at line $l in file $f to set indent to '$val'." );
100 161         468 return( $self->_set_get_scalar_as_object( 'indent', $val ) );
101             }
102 912         2538 return( $self->_set_get_scalar_as_object( 'indent' ) );
103             }
104              
105             sub keyframes_as_string
106             {
107 19     19 1 431 my( $self, $keyf ) = @_;
108 19 50       65 return( $self->error( "No keyframes rule object was provided." ) ) if( !defined( $keyf ) );
109 19 50       65 return( $self->error( "Keyframes object provided (", overload::StrVal( $keyf ), ") is not actually an CSS::Object::Rule::Keyframes" ) ) if( !$self->_is_a( $keyf, 'CSS::Object::Rule::Keyframes' ) );
110             ## no overloading;
111             ## Calling rule_as_string on each item in our stack
112 19     63   391 my $rule_str = $keyf->elements->map(sub{ $_->as_string })->join( "\n" )->scalar;
  63         3289  
113 19         2765 my $type = $keyf->type->tr( '_', '-' )->scalar;
114 19         2656 my $name = $keyf->name->scalar;
115 19         1000 my $nl = $self->new_line->scalar;
116 19 50       902 return( '@' . "${type} ${name}" . ( $self->open_brace_on_new_line ? $nl : ' ' ) . "{" . ( $self->open_brace_and_new_line ? $nl : '' ) . $rule_str . ( $self->close_brace_on_new_line ? $nl : ' ' ) . "}" );
    50          
    50          
117             }
118              
119 742     742 1 2984 sub new_line { return( shift->_set_get_scalar_as_object( 'new_line', @_ ) ); }
120              
121 409     409 1 47507 sub open_brace_on_new_line { return( shift->_set_get_boolean( 'open_brace_on_new_line', @_ ) ); }
122              
123 409     409 1 14072 sub open_brace_and_new_line { return( shift->_set_get_boolean( 'open_brace_on_new_line', @_ ) ); }
124              
125             ## Outdated. See elements_as_string
126             sub properties_as_string
127             {
128 0     0 1 0 my( $self, $properties ) = @_;
129             # no overloading;
130 0 0       0 return( $self->error( "No properties array was provided." ) ) if( !defined( $properties ) );
131 0 0       0 return( $self->error( "Properties provided is not an array object." ) ) if( !$self->_is_a( $properties, 'Module::Generic::Array' ) );
132             # return( join( '; ', map{ $_->name . ": " . $_->values->map(sub{ $_->value->scalar })->join( '' ) } @$properties ) );
133 0     0   0 return( $properties->map(sub{ $_->name->scalar . ': ' . $_->values->map(sub{ $_->value->scalar })->join( '' )->scalar })->join( ";" )->scalar );
  0         0  
  0         0  
134             }
135              
136             sub property_as_string
137             {
138 260     260 1 5190 my( $self, $prop ) = @_;
139             # no overloading;
140 260 50       978 return( $self->error( "No property object was provided." ) ) if( !defined( $prop ) );
141 260 50       941 return( $self->error( "Property object provied is not a CSS::Object::Property object." ) ) if( !$self->_is_a( $prop, 'CSS::Object::Property' ) );
142 260         4759 my $indent = $prop->format->indent->scalar;
143 260     260   12551 return( $prop->name->scalar . ': ' . $prop->values->map(sub{ $_->as_string })->join( '' )->scalar );
  260         14263  
144             }
145              
146 427     427 1 2698 sub property_separator { return( shift->_set_get_scalar_as_object( 'property_separator', @_ ) ); }
147              
148             sub restore_parameters
149             {
150 18     18 1 1238 my $self = shift( @_ );
151 18         36 my $this = shift( @_ );
152 18 50       66 return( $self->error( "Data provided is not an hash reference." ) ) if( !$self->_is_hash( $this ) );
153 18         173 my $params = $self->{_params};
154 18         48 foreach my $p ( @$params )
155             {
156 108         7742 $self->$p( $this->{ $p } );
157             }
158 18         2817 return( $self );
159             }
160              
161             sub rule_as_string
162             {
163 328     328 1 979 my( $self, $rule ) = @_;
164             # no overloading;
165             # my( $pack, $file, $line ) = caller;
166             # $self->message( 3, "Stringifying rule called from package $pack at line $line in file $file" );
167 328 50       1080 return( $self->error( "No rule object was provided." ) ) if( !defined( $rule ) );
168 328 0       1071 return( $self->error( "Rule object provided (", overload::Overloaded( $rule ) ? overload::StrVal( $rule ) : $rule ,") is not an actual rule object." ) ) if( !$self->_is_a( $rule, 'CSS::Object::Rule' ) );
    50          
169 328         6378 my $rule_indent = $rule->format->indent->scalar;
170 328         17427 my $nl = $self->new_line->scalar;
171             # $self->message( 3, "Indent string is '$rule_indent'." );
172             ## return( $rule->selectors_as_string . ' { ' . $rule->properties_as_string . " }\n" );
173             return(
174 328 50       15437 $rule_indent . $rule->selectors_as_string .
    50          
    50          
175             ( $self->open_brace_on_new_line ? $nl : ' ' ) .
176             $rule_indent . '{' .
177             ( $self->open_brace_and_new_line ? $nl : ' ' ) .
178             $rule->elements_as_string .
179             ( $self->close_brace_on_new_line ? $nl : ' ' ) .
180             "${rule_indent}}"
181             );
182             }
183              
184             sub selectors_as_string
185             {
186 328     328 1 14356 my( $self, $selectors ) = @_;
187 328     416   1951 return( $selectors->map(sub{ $_->name->scalar })->join( ', ' )->scalar );
  416         10728  
188             }
189              
190             sub value_as_string
191             {
192 268     268 1 4921 my( $self, $val ) = @_;
193 268 50       960 return( $self->error( "No value object was provided." ) ) if( !$self->_is_a( $val, 'CSS::Object::Value' ) );
194 268 50       5170 return( $self->error( "Value object provided is not a CSS::Object::Value object." ) ) if( !$self->_is_a( $val, 'CSS::Object::Value' ) );
195             # $self->messagef( 3, "%d comments before and %d comments after.", $val->comment_before->length, $val->comment_after->length );
196             return(
197 12     12   656 $val->comment_before->map(sub{ $_->as_string })->join( ' ' )->scalar . ( $val->comment_before->length > 0 ? ' ' : '' ) .
198             $val->value->as_string .
199 268 100   0   4706 ( $val->comment_after->length > 0 ? ' ' : '' ) . $val->comment_after->map(sub{ $_->as_string })->join( ' ' )->scalar
  0 50          
200             );
201             }
202              
203             sub values_as_string
204             {
205 0     0 1   my( $self, $values ) = @_;
206 0 0         return( $self->error( "No properties values array was provided." ) ) if( !defined( $values ) );
207 0 0         return( $self->error( "Properties values provided is not an array." ) ) if( !$self->_is_a( $values, 'Module::Generic::Array' ) );
208             ## return( join( '', map{ $_->value } @$values ) );
209             ## return( $values->map(sub{ $_->value->scalar })->join( '' )->scalar );
210 0     0     return( $values->map(sub{ $_->as_string })->join( '' )->scalar );
  0            
211             }
212              
213             1;
214              
215             __END__
216              
217             =encoding utf-8
218              
219             =head1 NAME
220              
221             CSS::Object::Format - CSS Object Oriented Stringificator
222              
223             =head1 SYNOPSIS
224              
225             use CSS::Object::Format;
226             my $format = CSS::Object::Format->new( debug => 3 ) ||
227             die( CSS::Object::Format->error );
228             my $prop = CSS::Object::Property->new(
229             format => $format,
230             debug => 3,
231             name => 'display',
232             value => 'inline-block',
233             ) || die( CSS::Object::Property->error );
234             print( $prop->as_string );
235              
236             =head1 VERSION
237              
238             v0.1.0
239              
240             =head1 DESCRIPTION
241              
242             L<CSS::Object::Format::Inline> is a CSS inline stringificator
243              
244             =head1 CONSTRUCTOR
245              
246             =head2 new
247              
248             To instantiate a new L<CSS::Object::Format> object, pass an hash reference of following parameters:
249              
250             =over 4
251              
252             =item I<debug>
253              
254             This is an integer. The bigger it is and the more verbose is the output.
255              
256             =back
257              
258             =head1 PARAMETERS
259              
260             The available parameters used to alter the formatting of the formatters are as follow. Please see each of them methods for their respective purpose and usage.
261              
262             =over 4
263              
264             =item * L</close_brace_on_new_line>
265              
266             =item * L</new_line>
267              
268             =item * L</open_brace_on_new_line>
269              
270             =item * L</open_brace_and_new_line>
271              
272             =item * L</indent>
273              
274             =item * L</property_separator>
275              
276             =back
277              
278             =head1 METHODS
279              
280             =head2 backup_parameters
281              
282             This will create a deep copy of this formatter's L</parameters> and return it.
283              
284             See L</restore_parameters>
285              
286             =head2 close_brace_on_new_line
287              
288             This takes a boolean value. If true, this will instruct the formatter to place the closing brace on a new line.
289              
290             =head2 comment_as_string
291              
292             Provided with a comment object, and this will return the comment formatted.
293              
294             =head2 copy_parameters_from
295              
296             Provided with another L<CSS::Object::Format> object, and this will copy all suitable L</parameters> to it.
297              
298             This is called from the L<format> methods in CSS element classes when a new format object is provided to the element.
299              
300             =head2 elements_as_string
301              
302             Provided with an array object (L<Module::Generic::Array>), and this will format all the elements and return a string.
303              
304             =head2 indent
305              
306             This is one of L</parameters> that sets the string to use as indent. Indent string can be provided in rule formatter or property formatter.
307              
308             This returns the current character value as a L<Module::Generic::Scalar> object.
309              
310             =head2 keyframes_as_string
311              
312             This formats the keyframe special rule and returns a string.
313              
314             =head2 new_line
315              
316             This sets or gets the new line character to be used for new lines.
317              
318             This returns the current character value as a L<Module::Generic::Scalar> object.
319              
320             =head2 open_brace_on_new_line
321              
322             This takes a boolean value. If true, this will instruct the formatter to place the opening brace on a new line.
323              
324             =head2 open_brace_and_new_line
325              
326             This takes a boolean value. If true, this will instruct the formatter to insert a new line after the opening brace.
327              
328             =head2 properties_as_string
329              
330             Provided with an array reference of a L<CSS::Object::Property> objects and this will format them and return their string representation.
331              
332             =head2 property_as_string
333              
334             Provided with a L<CSS::Object::Property> object and this will format it and return its string representation.
335              
336             =head2 property_separator
337              
338             This sets or gets the property separator. By default, this is a new line C<\n>
339              
340             If you want the formatter to put all properties on a single line, you could replace this default value with an empty string.
341              
342             This returns the current character value as a L<Module::Generic::Scalar> object.
343              
344             =head2 restore_parameters
345              
346             Provided with an hash reference, typically that created by L</backup_parameters> and this will restore this formatter's L</parameters>
347              
348             It returns our object
349              
350             =head2 rule_as_string
351              
352             Provided with a L<CSS::Object::Rule> object and this will format it and return its string representation.
353              
354             =head2 selectors_as_string
355              
356             Provided with an array reference of a L<CSS::Object::Selector> objects and this will format them and return their string representation.
357              
358             =head2 value_as_string
359              
360             Provided with a L<CSS::Object::Value> object and this will format it and return its string representation.
361              
362             =head2 values_as_string
363              
364             Provided with an array reference of a L<CSS::Object::Value> objects and this will format them and return their string representation.
365              
366             =head1 AUTHOR
367              
368             Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>
369              
370             =head1 SEE ALSO
371              
372             L<CSS::Object>
373              
374             =head1 COPYRIGHT & LICENSE
375              
376             Copyright (c) 2020 DEGUEST Pte. Ltd.
377              
378             You can use, copy, modify and redistribute this package and associated
379             files under the same terms as Perl itself.
380              
381             =cut