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   41 use strict;
  6         11  
  6         201  
14 6     6   30 use warnings;
  6         12  
  6         174  
15 6     6   41 use parent qw( Module::Generic );
  6         13  
  6         31  
16 6     6   349 use Devel::Confess;
  6         12  
  6         42  
17 6     6   9076 our $VERSION = 'v0.1.0';
18             };
19              
20             sub init
21             {
22 57     57 1 11368 my $self = shift( @_ );
23 57         187 $self->{new_line} = "\n";
24 57         138 $self->{open_brace_on_new_line} = 1;
25 57         127 $self->{close_brace_on_new_line} = 1;
26 57         129 $self->{open_brace_and_new_line} = 1;
27 57         163 $self->{indent} = '';
28 57         133 $self->{property_separator} = "\n";
29 57         132 $self->{_init_strict_use_sub} = 1;
30 57         315 $self->SUPER::init( @_ );
31 57         2788 $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         184 return( $self );
40             }
41              
42 18     18 1 270 sub backup_parameters { return( shift->clone ); }
43              
44 31     31 0 711 sub class { return( ref( $_[0] ) ); }
45              
46 371     371 1 9934 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 693 my( $self, $elem ) = @_;
51             # no overloading;
52 39 50       104 return( $self->error( "No comment object was provided." ) ) if( !defined( $elem ) );
53 39 50       145 return( $self->error( "Comment object provied is not a CSS::Object::Comment object." ) ) if( !$self->_is_a( $elem, 'CSS::Object::Comment' ) );
54 39         717 return( '/* ' . $elem->values->join( "\n" )->scalar . ' */' );
55             }
56              
57             sub copy_parameters_from
58             {
59 22     22 1 382 my $self = shift( @_ );
60 22   50     73 my $fmt = shift( @_ ) || return( $self->error( "No formatter object was provided to copy the parameters from." ) );
61 22 50       58 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         324 my $ok_params = $self->{_params};
65 22         64 for( @$ok_params )
66             {
67 132 50       4415 $self->$_( $fmt->$_ ) if( $fmt->can( $_ ) );
68             }
69 22         1118 return( $self );
70             }
71              
72             sub elements_as_string
73             {
74 295     295 1 5917 my( $self, $elems ) = @_;
75             # no overloading;
76 295 50       819 return( $self->error( "No elements array was provided." ) ) if( !defined( $elems ) );
77 295 50       1249 return( $self->error( "Elements provided is not an array object." ) ) if( !$self->_is_a( $elems, 'Module::Generic::Array' ) );
78 295         4504 my $result = Module::Generic::Array->new;
79 295         2546 my $nl = $self->new_line->scalar;
80 295         12040 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   27302 $result->push( $_->format->indent->scalar . $_->as_string . ( $_->isa( 'CSS::Object::Comment' ) ? '' : ';' ) );
87 295         12145 });
88 295         49151 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 15562 my $self = shift( @_ );
95 917 100       2123 if( @_ )
96             {
97 161         310 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         390 return( $self->_set_get_scalar_as_object( 'indent', $val ) );
101             }
102 756         1811 return( $self->_set_get_scalar_as_object( 'indent' ) );
103             }
104              
105             sub keyframes_as_string
106             {
107 17     17 1 381 my( $self, $keyf ) = @_;
108 17 50       69 return( $self->error( "No keyframes rule object was provided." ) ) if( !defined( $keyf ) );
109 17 50       72 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   368 my $rule_str = $keyf->elements->map(sub{ $_->as_string })->join( "\n" )->scalar;
  63         3160  
113 17         2684 my $type = $keyf->type->tr( '_', '-' )->scalar;
114 17         2737 my $name = $keyf->name->scalar;
115 17         898 my $nl = $self->new_line->scalar;
116 17 50       848 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 2516 sub new_line { return( shift->_set_get_scalar_as_object( 'new_line', @_ ) ); }
120              
121 371     371 1 37478 sub open_brace_on_new_line { return( shift->_set_get_boolean( 'open_brace_on_new_line', @_ ) ); }
122              
123 371     371 1 11493 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 3880 my( $self, $prop ) = @_;
139             # no overloading;
140 202 50       692 return( $self->error( "No property object was provided." ) ) if( !defined( $prop ) );
141 202 50       770 return( $self->error( "Property object provied is not a CSS::Object::Property object." ) ) if( !$self->_is_a( $prop, 'CSS::Object::Property' ) );
142 202         3399 my $indent = $prop->format->indent->scalar;
143 202     202   8255 return( $prop->name->scalar . ': ' . $prop->values->map(sub{ $_->as_string })->join( '' )->scalar );
  202         6193  
144             }
145              
146 391     391 1 2402 sub property_separator { return( shift->_set_get_scalar_as_object( 'property_separator', @_ ) ); }
147              
148             sub restore_parameters
149             {
150 18     18 1 707 my $self = shift( @_ );
151 18         30 my $this = shift( @_ );
152 18 50       50 return( $self->error( "Data provided is not an hash reference." ) ) if( !$self->_is_hash( $this ) );
153 18         111 my $params = $self->{_params};
154 18         40 foreach my $p ( @$params )
155             {
156 108         3778 $self->$p( $this->{ $p } );
157             }
158 18         960 return( $self );
159             }
160              
161             sub rule_as_string
162             {
163 292     292 1 688 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       813 return( $self->error( "No rule object was provided." ) ) if( !defined( $rule ) );
168 292 0       956 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         4887 my $rule_indent = $rule->format->indent->scalar;
170 292         12401 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       11465 $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 5865 my( $self, $selectors ) = @_;
187 292     350   1673 return( $selectors->map(sub{ $_->name->scalar })->join( ', ' )->scalar );
  350         7418  
188             }
189              
190             sub value_as_string
191             {
192 210     210 1 3917 my( $self, $val ) = @_;
193 210 50       764 return( $self->error( "No value object was provided." ) ) if( !$self->_is_a( $val, 'CSS::Object::Value' ) );
194 210 50       3760 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   216 $val->comment_before->map(sub{ $_->as_string })->join( ' ' )->scalar . ( $val->comment_before->length > 0 ? ' ' : '' ) .
198             $val->value->as_string .
199 210 100   0   3269 ( $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