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   36 use strict;
  6         10  
  6         188  
14 6     6   25 use warnings;
  6         11  
  6         140  
15 6     6   26 use parent qw( Module::Generic );
  6         9  
  6         25  
16 6     6   279 use Devel::Confess;
  6         11  
  6         28  
17 6     6   7536 our $VERSION = 'v0.1.0';
18             };
19              
20             sub init
21             {
22 57     57 1 9941 my $self = shift( @_ );
23 57         161 $self->{new_line} = "\n";
24 57         120 $self->{open_brace_on_new_line} = 1;
25 57         157 $self->{close_brace_on_new_line} = 1;
26 57         125 $self->{open_brace_and_new_line} = 1;
27 57         127 $self->{indent} = '';
28 57         117 $self->{property_separator} = "\n";
29 57         111 $self->{_init_strict_use_sub} = 1;
30 57         277 $self->SUPER::init( @_ );
31 57         2378 $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         147 return( $self );
40             }
41              
42 18     18 1 224 sub backup_parameters { return( shift->clone ); }
43              
44 31     31 0 662 sub class { return( ref( $_[0] ) ); }
45              
46 371     371 1 8956 sub close_brace_on_new_line { return( shift->_set_get_boolean( 'close_brace_on_new_line', @_ ) ); }
47              
48             sub comment_as_string
49             {
50 39     39 1 611 my( $self, $elem ) = @_;
51             # no overloading;
52 39 50       96 return( $self->error( "No comment object was provided." ) ) if( !defined( $elem ) );
53 39 50       141 return( $self->error( "Comment object provied is not a CSS::Object::Comment object." ) ) if( !$self->_is_a( $elem, 'CSS::Object::Comment' ) );
54 39         763 return( '/* ' . $elem->values->join( "\n" )->scalar . ' */' );
55             }
56              
57             sub copy_parameters_from
58             {
59 22     22 1 304 my $self = shift( @_ );
60 22   50     48 my $fmt = shift( @_ ) || return( $self->error( "No formatter object was provided to copy the parameters from." ) );
61 22 50       42 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         257 my $ok_params = $self->{_params};
65 22         45 for( @$ok_params )
66             {
67 132 50       3693 $self->$_( $fmt->$_ ) if( $fmt->can( $_ ) );
68             }
69 22         926 return( $self );
70             }
71              
72             sub elements_as_string
73             {
74 295     295 1 5145 my( $self, $elems ) = @_;
75             # no overloading;
76 295 50       795 return( $self->error( "No elements array was provided." ) ) if( !defined( $elems ) );
77 295 50       773 return( $self->error( "Elements provided is not an array object." ) ) if( !$self->_is_a( $elems, 'Module::Generic::Array' ) );
78 295         3860 my $result = Module::Generic::Array->new;
79 295         2092 my $nl = $self->new_line->scalar;
80 295         11364 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 217 100   217   23792 $result->push( $_->format->indent->scalar . $_->as_string . ( $_->isa( 'CSS::Object::Comment' ) ? '' : ';' ) );
87 295         10646 });
88 295         42352 return( $result->join( $prop_sep )->scalar );
89             }
90              
91             ## sub indent { return( shift->_set_get_scalar_as_object( 'indent', @_ ) ); }
92             sub indent
93             {
94 917     917 1 13454 my $self = shift( @_ );
95 917 100       1823 if( @_ )
96             {
97 161         231 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         365 return( $self->_set_get_scalar_as_object( 'indent', $val ) );
101             }
102 756         1540 return( $self->_set_get_scalar_as_object( 'indent' ) );
103             }
104              
105             sub keyframes_as_string
106             {
107 17     17 1 281 my( $self, $keyf ) = @_;
108 17 50       44 return( $self->error( "No keyframes rule object was provided." ) ) if( !defined( $keyf ) );
109 17 50       55 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 17     63   288 my $rule_str = $keyf->elements->map(sub{ $_->as_string })->join( "\n" )->scalar;
  63         2615  
113 17         2094 my $type = $keyf->type->tr( '_', '-' )->scalar;
114 17         1964 my $name = $keyf->name->scalar;
115 17         721 my $nl = $self->new_line->scalar;
116 17 50       658 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 668     668 1 2102 sub new_line { return( shift->_set_get_scalar_as_object( 'new_line', @_ ) ); }
120              
121 371     371 1 32732 sub open_brace_on_new_line { return( shift->_set_get_boolean( 'open_brace_on_new_line', @_ ) ); }
122              
123 371     371 1 10082 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 202     202 1 3436 my( $self, $prop ) = @_;
139             # no overloading;
140 202 50       607 return( $self->error( "No property object was provided." ) ) if( !defined( $prop ) );
141 202 50       656 return( $self->error( "Property object provied is not a CSS::Object::Property object." ) ) if( !$self->_is_a( $prop, 'CSS::Object::Property' ) );
142 202         2920 my $indent = $prop->format->indent->scalar;
143 202     202   7332 return( $prop->name->scalar . ': ' . $prop->values->map(sub{ $_->as_string })->join( '' )->scalar );
  202         5325  
144             }
145              
146 391     391 1 1923 sub property_separator { return( shift->_set_get_scalar_as_object( 'property_separator', @_ ) ); }
147              
148             sub restore_parameters
149             {
150 18     18 1 291 my $self = shift( @_ );
151 18         24 my $this = shift( @_ );
152 18 50       40 return( $self->error( "Data provided is not an hash reference." ) ) if( !$self->_is_hash( $this ) );
153 18         86 my $params = $self->{_params};
154 18         34 foreach my $p ( @$params )
155             {
156 108         3064 $self->$p( $this->{ $p } );
157             }
158 18         824 return( $self );
159             }
160              
161             sub rule_as_string
162             {
163 292     292 1 622 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 292 50       690 return( $self->error( "No rule object was provided." ) ) if( !defined( $rule ) );
168 292 0       1041 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 292         4360 my $rule_indent = $rule->format->indent->scalar;
170 292         10872 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 292 50       9881 $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 292     292 1 5087 my( $self, $selectors ) = @_;
187 292     350   1476 return( $selectors->map(sub{ $_->name->scalar })->join( ', ' )->scalar );
  350         6728  
188             }
189              
190             sub value_as_string
191             {
192 210     210 1 3187 my( $self, $val ) = @_;
193 210 50       674 return( $self->error( "No value object was provided." ) ) if( !$self->_is_a( $val, 'CSS::Object::Value' ) );
194 210 50       3178 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 8     8   200 $val->comment_before->map(sub{ $_->as_string })->join( ' ' )->scalar . ( $val->comment_before->length > 0 ? ' ' : '' ) .
198             $val->value->as_string .
199 210 100   0   2758 ( $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