File Coverage

blib/lib/Text/Pretty.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Text::Pretty;
2 1     1   26009 use strict;
  1         3  
  1         38  
3 1     1   4 use warnings;
  1         2  
  1         26  
4 1     1   360 use Types;
  0            
  0            
5             use Exporter;
6             use base qw/Exporter/;
7              
8             our $VERSION = '0.1.0';
9              
10             our %EXPORT_TAGS = (
11             prims => [qw(empty text space endl nest indent hcat onel) ]
12             , simple => [qw(semi comma colon dot equals quote bquote qquote
13             lparen rparen lbrack rbrack lbrace rbrace langle rangle)]
14             , struct => [qw(parents brackets braces quotes qquotes bquotes) ]
15             );
16              
17             $EXPORT_TAGS{combinators} = [ @{$EXPORT_TAGS{prims}}
18             , qw(vcat hsep punctuate surround)
19             ];
20              
21             our @EXPORT_OK = ( qw(is_empty words)
22             , @{$EXPORT_TAGS{combinators}}
23             , @{$EXPORT_TAGS{simple}}
24             , @{$EXPORT_TAGS{struct}}
25             );
26              
27             $EXPORT_TAGS{all} = \@EXPORT_OK;
28              
29             # document types
30             newtype Text::Pretty::Empty;
31             newtype Text::Pretty::Text;
32             newtype Text::Pretty::Space;
33             newtype Text::Pretty::Endl;
34             newtype Text::Pretty::Nest;
35             newtype Text::Pretty::HCat;
36             newtype Text::Pretty::Onel;
37              
38             uniontype Text::Pretty::Doc, qw(Text::Pretty::Empty
39             Text::Pretty::Text
40             Text::Pretty::Space
41             Text::Pretty::Endl
42             Text::Pretty::Nest
43             Text::Pretty::HCat
44             Text::Pretty::Onel);
45              
46             typeclass Text::Pretty::Print,
47             pretty => undef;
48              
49             # rendering method
50             # returns a string of the rendered document
51             # - document to render
52             # - options: document width and indent
53             instance Text::Pretty::Print, Text::Pretty::Doc,
54             pretty => sub { my( $doc, %opts ) = @_
55             ; my $w = $opts{width} || 80
56             ; my $ls = render_proc($doc,0,$w,[''])
57             ; join qq{\n}, @$ls
58             };
59              
60             # primitive documents
61             sub empty () { Empty() }
62             sub text ($) { Text(shift) }
63             sub space () { Space() }
64             sub endl () { Endl() }
65             sub nest ($$) { Nest(shift,shift) }
66             sub hcat ($) { HCat(shift) }
67             sub onel ($) { Onel(shift) }
68              
69             # document predicates
70             sub is_empty ($) { shift->isa('Empty') }
71              
72             # simple documents
73             sub semi () { text ';' }
74             sub comma () { text ',' }
75             sub colon () { text ':' }
76             sub dot () { text '.' }
77             sub equals () { text '=' }
78             sub quote () { text q{'} }
79             sub bquote () { text q{`} }
80             sub qquote () { text q{"} }
81             sub lparen () { text '(' }
82             sub rparen () { text ')' }
83             sub lbrack () { text '[' }
84             sub rbrack () { text ']' }
85             sub lbrace () { text '{' }
86             sub rbrace () { text '}' }
87             sub langle () { text '<' }
88             sub rangle () { text '>' }
89              
90             # generic document combinators
91             sub punctuate ($$) { my($p,$l)=@_;
92             hcat [do{ my @r = map {$_,$p} @{$l}; pop @r; @r} ] }
93             sub surround ($$$) { my($a,$v,$b)=@_; my $l = length $a->pretty;
94             hcat [ $a, (nest $l, hcat [$v, $b]) ] }
95              
96             # derived document combinators
97             sub vcat ($) { punctuate endl, [grep {not is_empty $_} @{shift()}] }
98             sub hsep ($) { punctuate space, [grep {not is_empty $_} @{shift()}] }
99             sub parents ($) { surround lparen, shift(), rparen }
100             sub brackets ($) { surround lbrack, shift(), rbrack }
101             sub braces ($) { surround lbrace, shift(), rbrace }
102             sub quotes ($) { surround quote, shift(), quote }
103             sub qquotes ($) { surround qquote, shift(), qquote }
104             sub bquotes ($) { surround text q{``}, shift(), text q{''} }
105             sub words ($) { my $s = shift
106             ; hcat [ hsep [map {text $_} split qr{\s+}, $s]
107             , $s =~ /\s$/sm
108             ? space
109             : () ] }
110              
111             sub render_proc
112             { no strict
113             ; my( $doc, $i, $w, $ls ) = @_
114             ; asserttype Text::Pretty::Doc, $doc
115             ; match $doc
116             => Text::Pretty::Text
117             => sub{ my $s = shift
118             ; length($ls->[$#{$ls}])+length($s) >= $w
119             && length($ls->[$#{$ls}]) != $i
120             ? do{ my $l = (q{ }x$i).$s
121             ; push @$ls, $l
122             }
123             : do{ my $l = pop @$ls
124             ; $l .= (q{ }x($i - length $l)) . $s
125             ; push @$ls, $l
126             }
127             ; $ls
128             }
129             => Text::Pretty::Space
130             => sub{ length($ls->[$#{$ls}]) >= $w
131             ? push @$ls, q{ }x$i
132             : do{ my $l = pop @$ls
133             ; $l .= q{ }
134             ; push @$ls, $l
135             }
136             ; $ls
137             }
138             => Text::Pretty::Endl
139             => sub{ push @$ls, q{ }x$i
140             ; $ls
141             }
142             => Text::Pretty::HCat
143             => sub{ $ls = render_proc($_,$i,$w,$ls) for @{shift()}
144             ; $ls
145             }
146             => Text::Pretty::Nest
147             => sub{ render_proc(pop, $i + shift, $w, $ls) }
148             => Text::Pretty::Onel
149             => sub{ my $e = text render_proc(shift, 0, 1_000_000, [''])->[0]
150             ; render_proc($e, $i, $w, $ls)
151             }
152             => Text::Pretty::Empty
153             => sub{ $ls }
154             }
155              
156             1;
157              
158             =head1 NAME
159              
160             Text::Pretty - The great new Text::Pretty!
161              
162             =head1 VERSION
163              
164             Version 0.1
165              
166             =head1 SYNOPSIS
167              
168             A generic pretty printing combinators.
169             More documentation is coming soon.
170              
171             =head1 EXPORT
172              
173             empty text space endl nest indent hcat onel
174             semi comma colon dot equals quote bquote qquote
175             lparen rparen lbrack rbrack lbrace rbrace langle rangle
176             parents brackets braces quotes qquotes bquotes
177             vcat hsep punctuate surround is_empty words
178              
179             =head1 AUTHOR
180              
181             Eugene Grigoriev, C<< >>
182              
183             =head1 BUGS
184              
185             Please report any bugs or feature requests to C, or through
186             the web interface at L. I will be notified, and then you'll
187             automatically be notified of progress on your bug as I make changes.
188              
189              
190              
191              
192             =head1 SUPPORT
193              
194             You can find documentation for this module with the perldoc command.
195              
196             perldoc Text::Pretty
197              
198              
199             You can also look for information at:
200              
201             =over 4
202              
203             =item * RT: CPAN's request tracker
204              
205             L
206              
207             =item * AnnoCPAN: Annotated CPAN documentation
208              
209             L
210              
211             =item * CPAN Ratings
212              
213             L
214              
215             =item * Search CPAN
216              
217             L
218              
219             =back
220              
221              
222             =head1 ACKNOWLEDGEMENTS
223              
224              
225             =head1 COPYRIGHT & LICENSE
226              
227             Copyright 2008 Eugene Grigoriev, all rights reserved.
228              
229             This program is free software; you can redistribute it and/or modify it
230             under the same terms as Perl itself.
231              
232