line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Text::Lorem::More; |
2
|
|
|
|
|
|
|
|
3
|
8
|
|
|
8
|
|
165317
|
use warnings; |
|
8
|
|
|
|
|
20
|
|
|
8
|
|
|
|
|
300
|
|
4
|
8
|
|
|
8
|
|
46
|
use strict; |
|
8
|
|
|
|
|
17
|
|
|
8
|
|
|
|
|
526
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
=head1 NAME |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
Text::Lorem::More - Generate formatted nonsense using random Latin words. |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 VERSION |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
Version 0.13 |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=head1 SYNOPSIS |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
Generate formatted nonsense using random Latin words. |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
use Text::Lorem::More; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
my $lorem = Text::Lorem::More->new; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# Greet a friend |
23
|
|
|
|
|
|
|
print "Hello, ", $lorem->fullname, "\n"; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# You could also ... |
26
|
|
|
|
|
|
|
print $lorem->process("Hello, +fullname\n"); |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
... or you can use the singleton: |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
use Text::Lorem::More qw(lorem); |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# Generate a random latin word |
33
|
|
|
|
|
|
|
my $latinwordoftheday = lorem->word; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Produce paragaphs in the Text::Lorem compatible manner |
36
|
|
|
|
|
|
|
my $content = lorem->paragraphs(3); |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
# Print 4 paragraphs, each separated by a single newline and tab: |
39
|
|
|
|
|
|
|
print "\t", scalar lorem->paragraph(4, "\n\t"); |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=cut |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
our $VERSION = '0.13'; |
44
|
|
|
|
|
|
|
|
45
|
8
|
|
|
8
|
|
47
|
use base qw/Exporter/; |
|
8
|
|
|
|
|
28
|
|
|
8
|
|
|
|
|
848
|
|
46
|
|
|
|
|
|
|
|
47
|
8
|
|
|
8
|
|
45
|
use Carp; |
|
8
|
|
|
|
|
37
|
|
|
8
|
|
|
|
|
745
|
|
48
|
8
|
|
|
8
|
|
22365
|
use Parse::RecDescent; |
|
8
|
|
|
|
|
500810
|
|
|
8
|
|
|
|
|
74
|
|
49
|
|
|
|
|
|
|
|
50
|
8
|
|
|
8
|
|
7384
|
use Text::Lorem::More::Source; |
|
8
|
|
|
|
|
21
|
|
|
8
|
|
|
|
|
6748
|
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
our $PARSER = Parse::RecDescent->new(<<'_END_'); |
53
|
|
|
|
|
|
|
content: |
54
|
|
|
|
|
|
|
content: pattern(s) { \@content } |
55
|
|
|
|
|
|
|
pattern: escape | variable | text |
56
|
|
|
|
|
|
|
escape: '++' { push @content, \"+" } |
57
|
|
|
|
|
|
|
variable: '+{' identifier '}' | '+' identifier |
58
|
|
|
|
|
|
|
identifier: /[A-Za-z0-9_]+/ { push @content, $item[1] } |
59
|
|
|
|
|
|
|
text: m/[^\+]+/ { push @content, \$item[1] } |
60
|
|
|
|
|
|
|
_END_ |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=head1 GENERATORS |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
To use a generator, call the method with the same name as the generator, |
65
|
|
|
|
|
|
|
To use the name generator, for example: |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
my $name = $lorem->name; |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Alternatively, you can use the C or C functions. |
70
|
|
|
|
|
|
|
To use the hostname generator, for example: |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
my $hostname = $lorem->hostname; |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# This will do the same thing ... |
75
|
|
|
|
|
|
|
my $otherhostname = $lorem->generate("+hostname"); |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=head2 word |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
Generates random latin word. |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
dicta |
82
|
|
|
|
|
|
|
sed |
83
|
|
|
|
|
|
|
repellat |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=head2 sentence |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
Generates between 4 and 9 words, with the first letter of the first word capitalized and a period following |
88
|
|
|
|
|
|
|
the last word. |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=head2 paragraph |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
Generates between 3 and 6 sentences, |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=head2 words $count |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
A Text::Lorem compatible words generator. |
97
|
|
|
|
|
|
|
Will generate $count words joined by " ". |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=head2 sentences $count |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
A Text::Lorem compatible sentences generator. |
102
|
|
|
|
|
|
|
Will generate $count sentences joined by " ". |
103
|
|
|
|
|
|
|
Each sentence contains between 4 and 9 words and ends with a period. |
104
|
|
|
|
|
|
|
B |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=head2 paragraphs $count |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
A Text::Lorem compatible sentences generator. |
109
|
|
|
|
|
|
|
Will generate $count paragraphs joined by "\n\n". |
110
|
|
|
|
|
|
|
Each paragraph contains between 3 and 6 sentences. |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=head2 name / firstname / lastname |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
Generates a random latin word with the first letter capitalized |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
Repellat |
117
|
|
|
|
|
|
|
Sed |
118
|
|
|
|
|
|
|
Ipsum |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=head2 fullname |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
Generates a firstname and lastname separated by a space |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
Lorem Dicta |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
=head2 username |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
Generates a random latin word |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
=head2 title |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
Generates between 1 and 3 words with the first letter of the first word capitalized |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=head2 description |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
Generates between 1 and 3 sentences. |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=head2 tld / topleveldomain |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
Generates a top level domain. |
141
|
|
|
|
|
|
|
Currently, this will either be "com", "org", or "net". |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
=head2 domain / domainname |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
Generates a domainname. |
146
|
|
|
|
|
|
|
Currently, this will attach "example" to a tld generator result. |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
example.com |
149
|
|
|
|
|
|
|
example.net |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=head2 host / hostname |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
Generates a hostname. |
154
|
|
|
|
|
|
|
Currently, this will either return a plain domainname, as above, or attach a latin word to a domainname result. |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
et.example.com |
157
|
|
|
|
|
|
|
example.org |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=head2 email / mail |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=head2 path |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=head2 httpurl |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
=head2 mailto |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=cut |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
our %GENERATOR = ( |
170
|
|
|
|
|
|
|
|
171
|
104
|
|
|
|
|
510
|
name => sub { [ sub { ucfirst lc $_ }, "+word" ] }, |
|
104
|
|
|
|
|
277
|
|
172
|
|
|
|
|
|
|
firstname => "name", |
173
|
|
|
|
|
|
|
lastname => "name", |
174
|
|
|
|
|
|
|
|
175
|
23
|
|
|
|
|
58
|
fullname => sub { ["+firstname +lastname"] }, |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
username => "word", |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
word => [ grep { length $_ } map { s/\W//g; lc } split m/\s/, <<_END_ ], |
180
|
|
|
|
|
|
|
alias consequatur aut perferendis sit voluptatem accusantium doloremque aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis Nemo enim ipsam voluptatem quia voluptas sit suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae et iusto odio dignissimos ducimus qui blanditiis praesentium laudantium, totam rem voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, Sed ut perspiciatis unde omnis iste natus error similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo porro quisquam est, qui minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? At vero eos et accusamus officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores doloribus asperiores repellat. |
181
|
|
|
|
|
|
|
_END_ |
182
|
|
|
|
|
|
|
|
183
|
0
|
|
|
|
|
0
|
title => sub { [ sub { ucfirst($_) }, "+word", 1 + int rand 3 ] }, |
|
0
|
|
|
|
|
0
|
|
184
|
|
|
|
|
|
|
|
185
|
0
|
|
|
|
|
0
|
description => sub { [ "+sentence", 1 + int rand 3 ] }, |
186
|
|
|
|
|
|
|
|
187
|
2
|
|
|
|
|
16
|
sentence => sub { [ sub { ucfirst($_) . "." }, "+word", 4 + int rand 6 ] }, |
|
2
|
|
|
|
|
8
|
|
188
|
|
|
|
|
|
|
|
189
|
0
|
|
|
|
|
0
|
paragraph => sub { [ "+sentence", 3 + int rand 4 ] }, |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
words => sub { |
192
|
24
|
|
|
|
|
29
|
$Text::Lorem::More::PRUNE = 1; |
193
|
24
|
|
|
|
|
74
|
return [ "+word", $Text::Lorem::More::COUNT, " " ]; |
194
|
|
|
|
|
|
|
}, |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
sentences => sub { |
197
|
5
|
|
|
|
|
9
|
my $lorem = shift; |
198
|
5
|
|
|
|
|
10
|
$Text::Lorem::More::PRUNE = 1; |
199
|
5
|
|
|
|
|
7
|
my $count = $Text::Lorem::More::COUNT; |
200
|
5
|
|
|
|
|
6
|
my @sentence; |
201
|
5
|
|
|
|
|
37
|
while ($count > 0) { |
202
|
21
|
|
|
|
|
65
|
push @sentence, ucfirst $lorem->words(4 + int rand 6); |
203
|
21
|
|
|
|
|
65
|
$count--; |
204
|
|
|
|
|
|
|
} |
205
|
5
|
|
|
|
|
63
|
return join(". ", @sentence) . "."; |
206
|
|
|
|
|
|
|
}, |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
paragraphs => sub { |
209
|
1
|
|
|
|
|
3
|
my $lorem = shift; |
210
|
1
|
|
|
|
|
2
|
$Text::Lorem::More::PRUNE = 1; |
211
|
1
|
|
|
|
|
2
|
my $count = $Text::Lorem::More::COUNT; |
212
|
1
|
|
|
|
|
3
|
my @paragraph; |
213
|
1
|
|
|
|
|
4
|
while ($count > 0) { |
214
|
4
|
|
|
|
|
19
|
push @paragraph, $lorem->sentences(3 + int rand 4); |
215
|
4
|
|
|
|
|
15
|
$count--; |
216
|
|
|
|
|
|
|
} |
217
|
1
|
|
|
|
|
7
|
return join("\n\n", @paragraph); |
218
|
|
|
|
|
|
|
}, |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
email => [ map { [ $_ ] } split m/\n/, <<_END_ ], |
221
|
|
|
|
|
|
|
+word\@+hostname |
222
|
|
|
|
|
|
|
+word\@+domainname |
223
|
|
|
|
|
|
|
_END_ |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
mail => "email", |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
relativepath => '', |
228
|
|
|
|
|
|
|
absolutepath => '', |
229
|
|
|
|
|
|
|
|
230
|
0
|
|
|
|
|
0
|
path => sub { [ "+word", 1 + int rand 6, "/" ] }, |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
httpurl => [ map { [ $_ ] } split m/\n/, <<_END_ ], |
233
|
|
|
|
|
|
|
http://+hostname+path |
234
|
|
|
|
|
|
|
http://+hostname:+port+path |
235
|
|
|
|
|
|
|
_END_ |
236
|
0
|
|
|
|
|
0
|
port => sub { int rand(1 + (2 ** 15)) }, |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
mailto => \"mailto:+email", |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
tld => "topleveldomain", |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
topleveldomain => [ split m/\s/, <<_END_ ], |
243
|
|
|
|
|
|
|
com org net |
244
|
|
|
|
|
|
|
_END_ |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
domain => "domainname", |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
domainname => [ map { [ $_ ] } split m/\n/, <<_END_ ], |
249
|
|
|
|
|
|
|
example.+tld |
250
|
|
|
|
|
|
|
_END_ |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
host => "hostname", |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
hostname => [ map { [ $_ ] } split m/\n/, <<_END_ ], |
255
|
|
|
|
|
|
|
+word.+domainname |
256
|
|
|
|
|
|
|
+domainname |
257
|
|
|
|
|
|
|
_END_ |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
); |
260
|
|
|
|
|
|
|
|
261
|
8
|
|
|
8
|
|
69
|
use constant MAXIMUM_RECURSION => 2 ** 12; |
|
8
|
|
|
|
|
15
|
|
|
8
|
|
|
|
|
498
|
|
262
|
8
|
|
|
8
|
|
42
|
use constant GENERATOR => \%GENERATOR; |
|
8
|
|
|
|
|
15
|
|
|
8
|
|
|
|
|
5086
|
|
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
=head1 EXPORT |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=cut |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
our @EXPORT_OK = qw(lorem); |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=head1 FUNCTIONS |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
=head2 new [$source] |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
Construct a new Text::Lorem::More object |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
=cut |
277
|
|
|
|
|
|
|
sub new { |
278
|
9
|
|
|
9
|
1
|
3235
|
my $self = bless {}, shift; |
279
|
9
|
|
|
|
|
26
|
my $source; |
280
|
9
|
50
|
|
|
|
151
|
if (@_) { |
281
|
0
|
0
|
|
|
|
0
|
if (ref $_[0] eq "HASH") { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
282
|
0
|
|
|
|
|
0
|
my $generator = shift; |
283
|
0
|
|
|
|
|
0
|
my $priority = shift; |
284
|
0
|
0
|
|
|
|
0
|
$source = new Text::Lorem::More::Source($source, $priority) if ref $source eq "HASH"; |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
elsif (UNIVERSAL::isa($_[0], "Text::Lorem::More::Source")) { |
287
|
0
|
|
|
|
|
0
|
$source = shift; |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
elsif (! defined $_[0]) { |
290
|
0
|
|
|
|
|
0
|
$source = new Text::Lorem::More::Source; |
291
|
|
|
|
|
|
|
} |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
else { |
294
|
9
|
|
|
|
|
46
|
$source = $self->_DEFAULT_SOURCE->copy; |
295
|
|
|
|
|
|
|
} |
296
|
9
|
|
|
|
|
48
|
$self->{source} = $source; |
297
|
9
|
|
|
|
|
67
|
return $self; |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=head2 generate $pattern [, $count, $separator] |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
Generate some text using the specified pattern. |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
C is faster than C, as C uses regex to perform substitution. |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
In list context, return a list with C<$count> number of "words" |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
In scalar context, return C<$pattern> repeated C<$count> times and joined by C<$separator>. |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
B |
311
|
|
|
|
|
|
|
B |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
The default for C<$count> is 1. |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
The default for C<$separator> is " ". |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
A pattern will usually contain one or more generator tokens. For example: |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
+name |
320
|
|
|
|
|
|
|
+fullname |
321
|
|
|
|
|
|
|
+word+word+word+word |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
The pattern can also contain other text: |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
+name@+domainname |
326
|
|
|
|
|
|
|
"+firstname +lastname" |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
Sometimes you might need to enclose the token identifier between C<+{> and C<}> |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
For example, the following pattern won't work right: |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
prefix+namesuffix |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
But this will: |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
prefix+{name}suffix |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
If you need to include a '+' in your pattern, you'll have to use C instead. |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
=cut |
341
|
|
|
|
|
|
|
sub generate { |
342
|
294
|
|
|
294
|
1
|
365
|
my $self = shift; |
343
|
|
|
|
|
|
|
# _generate may recurse any number of times. |
344
|
|
|
|
|
|
|
# the RECURSION counter makes sure it doesn't get out of hand. |
345
|
294
|
|
|
|
|
349
|
local $Text::Lorem::More::RECURSION = 0; |
346
|
294
|
|
|
|
|
592
|
return $self->_generate(@_); |
347
|
|
|
|
|
|
|
} |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=head2 process $text |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
Process a block of text, performing pattern substitutions as they're found. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
process is slower than generate, as process uses L. |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
To escape '+', simply repeat it. For example, to produce "2 + 2" you would submit: |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
2 ++ 2 |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
Please see C for more information. |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=cut |
362
|
|
|
|
|
|
|
sub process { |
363
|
5
|
|
|
5
|
1
|
8
|
my $self = shift; |
364
|
|
|
|
|
|
|
# _process may recurse any number of times. |
365
|
|
|
|
|
|
|
# the RECURSION counter makes sure it doesn't get out of hand. |
366
|
5
|
|
|
|
|
8
|
local $Text::Lorem::More::RECURSION = 0; |
367
|
5
|
|
|
|
|
22
|
return $self->_process(@_); |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
=head2 source |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
Return the generator source for this instance. |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
=cut |
375
|
|
|
|
|
|
|
sub source { |
376
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
377
|
0
|
|
|
|
|
0
|
return $self->{source}; |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=head2 lorem |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
A L singleton. |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=cut |
385
|
272
|
|
|
272
|
1
|
138913
|
sub lorem() { __PACKAGE__->_singleton } |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
sub _DEFAULT_SOURCE { |
388
|
9
|
|
66
|
9
|
|
82
|
return our $SOURCE ||= do { |
389
|
7
|
|
|
|
|
177
|
$SOURCE = new Text::Lorem::More::Source; |
390
|
7
|
|
|
|
|
49
|
$SOURCE->push(GENERATOR); |
391
|
7
|
|
|
|
|
59
|
$SOURCE; |
392
|
|
|
|
|
|
|
} |
393
|
|
|
|
|
|
|
} |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
sub AUTOLOAD { |
396
|
9
|
|
|
9
|
|
104
|
my $self = shift->_self; |
397
|
9
|
|
|
|
|
22
|
my $method = our $AUTOLOAD; |
398
|
9
|
|
|
|
|
71
|
$method =~ s/.*:://; |
399
|
|
|
|
|
|
|
|
400
|
9
|
50
|
|
|
|
51
|
if ($self->{source}->find($method)) { |
401
|
8
|
|
|
8
|
|
52
|
no strict 'refs'; |
|
8
|
|
|
|
|
24
|
|
|
8
|
|
|
|
|
9885
|
|
402
|
9
|
|
|
292
|
|
82
|
*$AUTOLOAD = sub { my $self = shift; $self->generate("+$method", @_) }; |
|
292
|
|
|
|
|
359
|
|
|
292
|
|
|
|
|
986
|
|
403
|
9
|
|
|
|
|
25
|
unshift @_, $self; |
404
|
9
|
|
|
|
|
48
|
goto &$AUTOLOAD; |
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
else { |
407
|
0
|
|
|
|
|
0
|
carp "no such generatelet for \"$method\" found"; |
408
|
0
|
|
|
|
|
0
|
return ""; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
} |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
our ($RECURSION, $COUNT, $PRUNE); |
413
|
|
|
|
|
|
|
sub _process { |
414
|
5
|
|
|
5
|
|
6
|
my $self = shift; |
415
|
5
|
|
|
|
|
7
|
my $content = shift; |
416
|
5
|
|
|
|
|
5
|
my $count = shift; |
417
|
5
|
|
|
|
|
6
|
my $separator = shift; |
418
|
|
|
|
|
|
|
|
419
|
5
|
|
|
|
|
8
|
$RECURSION += 1; |
420
|
5
|
50
|
|
|
|
13
|
croak "Too much recursion ($RECURSION) on \"$content\"" if $RECURSION >= MAXIMUM_RECURSION; |
421
|
|
|
|
|
|
|
|
422
|
5
|
50
|
|
|
|
13
|
$count = 1 unless defined $count; |
423
|
5
|
50
|
|
|
|
28
|
croak "\$count ($count) should be a number" unless $count =~ m/^\d+$/; |
424
|
|
|
|
|
|
|
|
425
|
5
|
50
|
|
|
|
22
|
$separator = " " unless defined $separator; |
426
|
|
|
|
|
|
|
|
427
|
5
|
|
|
|
|
6
|
local $Text::Lorem::More::COUNT = $count; $COUNT = $COUNT; |
|
5
|
|
|
|
|
6
|
|
428
|
5
|
|
|
|
|
7
|
local $Text::Lorem::More::PRUNE = 0; |
429
|
|
|
|
|
|
|
|
430
|
5
|
|
|
|
|
6
|
my @content; |
431
|
5
|
|
|
|
|
13
|
while ($count >= 0) { |
432
|
10
|
|
|
|
|
21
|
my $yield = ""; |
433
|
10
|
|
|
|
|
83
|
my $parseryield = $PARSER->content($content); |
434
|
10
|
|
|
|
|
23314
|
for (@$parseryield) { |
435
|
20
|
100
|
|
|
|
69
|
$yield .= ref $_ ? $$_ : $self->_replace_pattern($_); |
436
|
|
|
|
|
|
|
} |
437
|
10
|
50
|
|
|
|
23
|
push @content, $yield if $Text::Lorem::More::PRUNE; |
438
|
10
|
100
|
66
|
|
|
119
|
last if 0 == $count || $Text::Lorem::More::PRUNE; |
439
|
5
|
|
|
|
|
9
|
push @content, $yield; |
440
|
5
|
|
|
|
|
18
|
$count--; |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
5
|
50
|
|
|
|
52
|
return $content[0] if 1 == @content; |
444
|
0
|
0
|
|
|
|
0
|
return wantarray ? @content : join $separator, @content; |
445
|
|
|
|
|
|
|
} |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
sub _generate { |
448
|
2955
|
|
|
2955
|
|
3196
|
my $self = shift; |
449
|
2955
|
|
|
|
|
3198
|
my $pattern = shift; |
450
|
2955
|
|
|
|
|
2698
|
my $count = shift; |
451
|
2955
|
|
|
|
|
2489
|
my $separator = shift; |
452
|
2955
|
|
|
|
|
3009
|
my $fast = shift; |
453
|
|
|
|
|
|
|
|
454
|
2955
|
|
|
|
|
3813
|
$RECURSION += 1; |
455
|
2955
|
50
|
|
|
|
5082
|
croak "Too much recursion ($RECURSION) on \"$pattern\"" if $RECURSION >= MAXIMUM_RECURSION; |
456
|
|
|
|
|
|
|
|
457
|
2955
|
100
|
|
|
|
5662
|
$count = 1 unless defined $count; |
458
|
2955
|
50
|
|
|
|
9452
|
croak "\$count ($count) should be a number" unless $count =~ m/^\d+$/; |
459
|
|
|
|
|
|
|
|
460
|
2955
|
100
|
|
|
|
5050
|
$separator = " " unless defined $separator; |
461
|
|
|
|
|
|
|
|
462
|
2955
|
|
|
|
|
3386
|
local $Text::Lorem::More::COUNT = $count; $COUNT = $COUNT; |
|
2955
|
|
|
|
|
2812
|
|
463
|
2955
|
|
|
|
|
3055
|
local $Text::Lorem::More::PRUNE = 0; |
464
|
|
|
|
|
|
|
|
465
|
2955
|
|
|
|
|
2909
|
my @content; |
466
|
2955
|
|
|
|
|
5260
|
while ($count >= 0) { |
467
|
6027
|
|
|
|
|
6388
|
my $pattern = $pattern; |
468
|
6027
|
|
66
|
|
|
24460
|
$pattern =~ s/\+\{(\w+)\}|\+(\w+)/$self->_replace_pattern($1 || $2)/eg; |
|
7611
|
|
|
|
|
27073
|
|
469
|
6026
|
100
|
|
|
|
12387
|
push @content, $pattern if $Text::Lorem::More::PRUNE; |
470
|
6026
|
100
|
66
|
|
|
15805
|
last if 0 == $count || $Text::Lorem::More::PRUNE; |
471
|
3072
|
|
|
|
|
4338
|
push @content, $pattern; |
472
|
3072
|
|
|
|
|
7564
|
$count--; |
473
|
|
|
|
|
|
|
} |
474
|
|
|
|
|
|
|
|
475
|
2954
|
100
|
|
|
|
11775
|
return $content[0] if 1 == @content; |
476
|
27
|
50
|
|
|
|
180
|
return wantarray ? @content : join $separator, @content; |
477
|
|
|
|
|
|
|
} |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
sub _replace_pattern { |
480
|
7619
|
|
|
7619
|
|
7928
|
my $self = shift; |
481
|
7619
|
|
|
|
|
9861
|
my $pattern = shift; |
482
|
|
|
|
|
|
|
|
483
|
7619
|
|
|
|
|
30170
|
my $generatelet = $self->{source}->find($pattern); |
484
|
|
|
|
|
|
|
|
485
|
7618
|
50
|
|
|
|
15712
|
return $pattern unless $generatelet; |
486
|
|
|
|
|
|
|
|
487
|
7618
|
|
|
|
|
6934
|
my $content; |
488
|
7618
|
100
|
|
|
|
17424
|
if (ref $generatelet eq "ARRAY") { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
489
|
7459
|
|
|
|
|
14448
|
$content = $generatelet->[int rand @$generatelet]; |
490
|
|
|
|
|
|
|
} |
491
|
|
|
|
|
|
|
elsif (ref $generatelet eq "SCALAR") { |
492
|
0
|
|
|
|
|
0
|
$content = $$generatelet; |
493
|
|
|
|
|
|
|
} |
494
|
|
|
|
|
|
|
elsif (ref $generatelet eq "CODE") { |
495
|
159
|
|
|
|
|
301
|
$content = $generatelet->($self); |
496
|
|
|
|
|
|
|
} |
497
|
|
|
|
|
|
|
else { |
498
|
0
|
|
|
|
|
0
|
croak "Don't know how to run/handle generatelet \"$generatelet\""; |
499
|
|
|
|
|
|
|
} |
500
|
|
|
|
|
|
|
|
501
|
7618
|
100
|
|
|
|
13871
|
if (ref $content eq "ARRAY") { |
502
|
2661
|
|
|
|
|
2476
|
my $filter; |
503
|
2661
|
100
|
|
|
|
5340
|
$filter = shift @$content if ref $content->[0] eq "CODE"; |
504
|
2661
|
|
|
|
|
4067
|
my ($pattern, $count, $separator) = @$content; |
505
|
2661
|
|
|
|
|
4926
|
local $_ = $self->_generate($pattern, $count, $separator); |
506
|
2661
|
100
|
|
|
|
4687
|
$_ = $filter->($_) if $filter; |
507
|
2661
|
|
|
|
|
5387
|
$content = $_; |
508
|
|
|
|
|
|
|
} |
509
|
|
|
|
|
|
|
|
510
|
7618
|
|
|
|
|
23333
|
return $content; |
511
|
|
|
|
|
|
|
} |
512
|
|
|
|
|
|
|
|
513
|
9
|
50
|
|
9
|
|
39
|
sub _self($) { return ref $_[0] ? $_[0] : $_[0]->_singleton } |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
sub _singleton { |
517
|
272
|
|
|
272
|
|
453
|
my $class = shift; |
518
|
272
|
|
66
|
|
|
1081
|
return our $singleton ||= $class->new; |
519
|
|
|
|
|
|
|
} |
520
|
|
|
|
|
|
|
|
521
|
0
|
|
|
0
|
|
|
sub DESTROY { |
522
|
|
|
|
|
|
|
} |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
=head1 AUTHOR |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
Robert Krimen, C<< >> |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
=head1 SEE ALSO |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
L |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
L |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
L |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
=head1 SOURCE |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
You can contribute or fork this project via GitHub: |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
L |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
git clone git://github.com/robertkrimen/text-lorem-more.git Text-Lorem-More |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
Thanks to Adeola Awoyemi for writing L |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
Copyright 2006 Robert Krimen, all rights reserved. |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
553
|
|
|
|
|
|
|
under the same terms as Perl itself. |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
=head1 BUGS |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
Probaby a lot. Please report them (as below) and I'll take a look. |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
Please report any bugs or feature requests to |
560
|
|
|
|
|
|
|
C, or through the web interface at |
561
|
|
|
|
|
|
|
L. |
562
|
|
|
|
|
|
|
I will be notified, and then you'll automatically be notified of progress on |
563
|
|
|
|
|
|
|
your bug as I make changes. |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
=head1 SUPPORT |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
perldoc Text::Lorem::More |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
You can also look for information at: |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
=over 4 |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
L |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
=item * CPAN Ratings |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
L |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
L |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
=item * Search CPAN |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
L |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
=back |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
=cut |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
1; # End of Text::Lorem::More |