| 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
|
|
|
|
|
|
|
|