poetry_from_poetry_with_variations.pl 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 09 February 2017
  5. # https://github.com/trizen
  6. # An experimental poetry generator, using a given poetry as input,
  7. # replacing words with random words from groups of alike ending words.
  8. # usage:
  9. # perl poetry_from_poetry.pl [poetry.txt] [wordlists]
  10. use 5.016;
  11. use strict;
  12. use autodie;
  13. use warnings;
  14. use open IO => ':utf8', ':std';
  15. use File::Find qw(find);
  16. my $poetry_file = shift(@ARGV);
  17. @ARGV
  18. || die "usage: $0 [poetry.txt] [wordlists]\n";
  19. my $poetry = do {
  20. open my $fh, '<', $poetry_file;
  21. local $/;
  22. <$fh>;
  23. };
  24. my $ending_len = 3; # word ending length
  25. my $group_len = 0; # the number of words in a group - 1
  26. my $word_regex = qr/[\pL]+(?:-[\pL]+)?/;
  27. my %words;
  28. my %seen;
  29. sub collect_words {
  30. my ($file) = @_;
  31. open my $fh, '<', $file;
  32. my $content = do {
  33. local $/;
  34. <$fh>;
  35. };
  36. close $fh;
  37. while ($content =~ /($word_regex(?:\h+$word_regex){$group_len})/go) {
  38. my $word = CORE::fc($1);
  39. my $len = $ending_len;
  40. if (length($word) > $len) {
  41. next if $seen{$word}++;
  42. push @{$words{substr($word, -$len)}}, $word;
  43. }
  44. }
  45. }
  46. find {
  47. no_chdir => 1,
  48. wanted => sub {
  49. if ((-f $_) and (-T _)) {
  50. collect_words($_);
  51. }
  52. },
  53. } => @ARGV;
  54. my @keys = keys(%words);
  55. my %endings;
  56. $poetry =~ s{($word_regex)}{
  57. my $word = $1;
  58. my $len = $ending_len;
  59. if (length($word) <= $len) {
  60. $word;
  61. }
  62. else {
  63. my $ending = CORE::fc(substr($word, -$len));
  64. my $key = ($endings{$ending} //= $keys[rand @keys]);
  65. exists($words{$key}) ? $words{$key}[rand @{$words{$key}}] : $word;
  66. }
  67. }ge;
  68. say $poetry;