Here's some 'work in progress' - ie, it'll never be finished.., but as it finally works, I thought it was time to let it loose in the Monastry for taming... It produces surreal limericks of the 'Edward Lear' type (ie, not very funny and having a last line based on the first), but they rhyme, scan, and sometimes almost make sense.
I wanted to use Lingua::EN::Rhyme, but it needs a MYSQL db setting up, so I plumped for parsing rhymezone.com instead.
I was also, up to last night, picking a random location from WWW::Gazetteer::HeavensAbove, but suddenly the server stopped...hope it wasn't me :) So for now, supply a placename as an argument.
Again, for the random words, I wanted to use Lingua::EN::Dict, but it's seriously broke :( so instead it picks random words from /usr/share/dict and looks them up using Net::Dict.
It can be a little slow (lots of lookups), hence the 'I'm still working' print statements.
All suggestions welcome :)
#!usr/bin/perl
# SurreaLearruS
use strict; # as if...
use Net::Dict; # lookups for word type
# use WWW::Gazetteer::HeavensAbove; #when it works again, random pl
+aces..
use Lingua::EN::Syllable;
use LWP::Simple;
use Algorithm::Numerical::Shuffle qw /shuffle/; # Ta Abigail :)
my $place = @ARGV[0] or die "Usage - limerick placename\n";
my $dict = Net::Dict->new('dict.org');
my $prhyme = rhyme($place,'n') or die "No rhyme for $place!\n";
print "found rhyme for $place...\n";
my $place_syll = syllable($place);
# set up word array,
my @words; # thanks to BrowserUK :)
open FILE, '<', '/usr/share/dict/words' or die $!; # I liked Tie::File
+ solution too,
while(<FILE>) {push @words, tell FILE;} # but needs permissions to
+rw dict..
print "loaded words\n";
my %people = ( #people, syllables and s/he
'lady'=>[2,'s'],
'woman'=>[2,'s'],
'man'=>[1],
'boy'=>[1],
'girl'=>[1,'s']
); # etc..
my @people = keys %people;
my $person = $people[int(rand(@people))];
my $psyllables = $people{$person}[0];
my $gender = $people{$person}[1];
my $qualifier = int(rand(2));
if ($qualifier) {
$person = ((int(rand(2))) ?'old ':'young ').$person;
$psyllables++;
}
print "got person...\n";
my $conj = ('by','with','in')[int(rand(3))];
my $noun1 = rand_word('n');
print "picked 1st noun...\n";
my ($noun2,$n2rhyme);
while (!$n2rhyme) {
$noun2 = rand_word('n');
$n2rhyme = rhyme($noun2,'n');
}
print "picked 2nd noun & rhyme...\n";
my $once = 'once' if ($psyllables + $place_syll) < 4;
print "There $once was ",indef($person)," $person from $place,\n",
"who ",past(rand_word('v'))," ",indef($noun1)," $noun1 $conj ",ind
+ef($prhyme)," $prhyme,\n",
$gender,"he ",past(rand_word('v'))," ",indef($noun2)," $noun2,\n",
"and ",past(rand_word('v'))," ",indef($n2rhyme)," $n2rhyme,\n",
"that ",rand_word('adj')," $person from $place.\n";
close FILE;
exit;
sub rhyme {
my ($word, $type) = @_;
my $page = LWP::Simple::get("http://www.rhymezone.com/r/rhyme.cgi?
+Word=$word&typeofrhyme=perfect&org1=syl&org2=l");
my @rhymes;
push @rhymes, $1 while ($page =~ /HREF="d\?u=(\w+?)"/sg);
@rhymes = shuffle (@rhymes);
foreach (@rhymes) {
return $_ if ($_ ne $word && word_type($_) eq $type);
}
return 0;
}
sub rand_word {
my $type = shift();
my ($word,$t);
my $start = rand(@words);
while ($t ne $type) {
$start = 0 if ($start++ > $#words);
$word = do{ seek FILE, $words[$start], 0; <FILE>;};
chomp $word;
next if ($word eq ucfirst($word));#skip proper nouns
$t = word_type($word);
}
$word;
}
#parse Wordnet Definition for 'n 1:' etc...
#will be improved to take all meanings into account - for now just ret
+urn first one.
sub word_type {
my $word = shift();
my $h = $dict->define($word,'wn');
$h->[0][1] =~ /\b(\w+)\s+1?:/s;
return $1;
}
sub get_places { #awww - it was so sweet too...:)
my ($pattern,$country) = @_;
my $atlas = WWW::Gazetteer::HeavensAbove->new;
my @az = $atlas->find($pattern,$country);
return @az;
}
sub indef {return ((shift =~ /^[aeoiu]/i) ? 'an' : 'a');} #dodgy, but
+works for most cases :)
sub past {my $v = shift(); return ($v =~/^(.*)y/) ?$1.'ied' : $v .(($v
+ =~/e$/) ? "d":"ed");} # even dodgier!
My favourite so far......
There once was a lady from york,
who amassed an unpleasantness with a stork,
she reestablished a hull,
and imperiled a cull,
that barometric lady from york.
Enjoy!
Update - fixed the gender and 'once' bugs.
Update2 - improved 'past'