poefy 0.6.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0defb6d9a94a5162826c5815c0f9f1aac7b98c91
4
- data.tar.gz: a8c83d5c423ea918252c47a2aa74897d44ad2c72
3
+ metadata.gz: c669c795f0aa86b7641c6b0246bf7af4c70a044c
4
+ data.tar.gz: 1d6b45c4c036677c7dcffa769576eac72e997d7c
5
5
  SHA512:
6
- metadata.gz: a09920a71f8feced4ddd7a079c06f8ea2c763f7fa84adb47da81d075d993d94b4ba65e8e1889d3be57081c634f04edb77fee46a3beaf414cdf6ea58bf229eb09
7
- data.tar.gz: 5ee1495dab167b26d4ec006b3fadd18e93a85d483e2730f061080dc6cd32988c0d50d5fca542b52d47b48a6abfc9b15e3c30939c477067a238097a525802f988
6
+ metadata.gz: 83b5d17cea7d870b77cd04ee06120f24ccd7b09fc4184472c1c9a893e0c9aeea64b9d255b9585515689ff06e19a1d9fe3cd841c1eda89d124a2807ff9b25a5c3
7
+ data.tar.gz: 58e698d002d74198bbd10fbea4a66f402a664e8d182a6c1c4ee2455b3829ad068b3de81437f03d8ad5d9ab76585ce79357de5179c795f356b539f8d543b9fea1
data/.gitignore CHANGED
@@ -67,6 +67,9 @@ desktop.ini
67
67
  work*.rb
68
68
  /~/
69
69
 
70
+ # Config files
71
+ settings.yml
72
+
70
73
  # Data files
71
74
  /data/
72
75
 
data/.rspec CHANGED
@@ -1,2 +1 @@
1
- --color
2
1
  --require spec_helper
data/README.md CHANGED
@@ -1,8 +1,16 @@
1
+ __Warning: This project is undergoing serious revision at the moment, and parts of this readme are invalid.__
2
+
3
+ __For the correct documentation for the most recent gem version (0.6.1), please see the revision here:
4
+ [README.md](https://github.com/nossidge/poefy/blob/fb4e39a88296074075a8ad1708e60747f3323baf/README.md)__
5
+
6
+ __Version 1.0.0 is coming soon, with Postgres support as the major feature.__
7
+
8
+
1
9
  # Poefy
2
10
 
3
11
  by [Paul Thompson](https://tilde.town/~nossidge) - nossidge@gmail.com
4
12
 
5
- Create poems from an input text file, by generating and querying a SQLite database that describes each line.
13
+ Create rhyming poems from an input text file, by generating and querying a SQLite or PostgreSQL database that describes each line.
6
14
 
7
15
  Poems are created using a template to select lines from the database, according to closing rhyme, syllable count, and regex matching.
8
16
 
@@ -11,59 +19,95 @@ I wrote this because I was banging my head against a wall trying to use [Tracery
11
19
 
12
20
  ## Installation
13
21
 
14
- Add this line to your application's Gemfile:
22
+ ### Install the base gem
15
23
 
16
- ```ruby
17
- gem 'poefy'
18
- ```
24
+ $ gem install poefy
19
25
 
20
- And then execute:
21
26
 
22
- $ bundle
27
+ ### Install a database gem
23
28
 
24
- Or install it yourself as:
29
+ You have two options when it comes to databases.
25
30
 
26
- $ gem install poefy
27
31
 
28
- The repo comes with some text files included. To generate databases for these files, execute the special `make_dbs` command:
32
+ #### PostgreSQL
33
+
34
+ Install [PostgreSQL 9.0+](https://www.postgresql.org/download/)
35
+
36
+ Install the below gem.
37
+
38
+ $ gem install poefy-pg
39
+
40
+ Create a new user:
41
+
42
+ username: 'poefy'
43
+ password: 'poefy'
44
+
45
+ Then create a new database, with the above user as the owner:
29
46
 
30
- $ poefy make_dbs
47
+ database: 'poefy'
31
48
 
32
- The code rather hackily uses system to call `sqlite3`, so make sure you have that installed and in your PATH.
49
+ Everything is called 'poefy'. Nice and easy.
50
+
51
+
52
+ #### SQLite
53
+
54
+ Install [SQLite 3.0+](https://sqlite.org/download.html)
55
+
56
+ Just install the below gem. There is no further setup needed.
57
+
58
+ $ gem install poefy-sqlite3
59
+
60
+
61
+ ### Set up some example corpora
62
+
63
+ The repo comes with some initial text files included. To generate corpora for these files, execute the special `poefy_make` binary:
64
+
65
+ $ poefy_make
66
+
67
+ This command will also setup a `settings.yml` file in the gem root. By default it will be set to 'pg' or 'sqlite3', depending on which gem you installed. If you need to change that setting you can run either of the below:
68
+
69
+ $ poefy -D pg
70
+ $ poefy -D sqlite3
71
+
72
+ You can use the `-D` option by itself without the argument to see the current database setting.
33
73
 
34
74
 
35
75
  ## Usage
36
76
 
37
77
  ### From the Command Line
38
78
 
39
- Make a poefy database from a text file:
79
+ To make a poefy corpus from a text file, run either of the below:
80
+
81
+ $ poefy shakespeare -m < shakespeare_sonnets.txt
82
+ $ poefy shakespeare --make < shakespeare_sonnets.txt
40
83
 
41
- $ poefy shakespeare -o < shakespeare_sonnets.txt
84
+ This will create a corpus describing each line of Shakespeare's sonnets. The type of corpus depends on whether you are using PosgreSQL (saved as a table in the 'poefy' database) or SQLite (saved to a database file as ROOT/data/CORPUS.db).
42
85
 
43
- Now, whenever you want to make poems using Shakespeare's lines, you can just use `poefy shakespeare` and it will read from the already created database:
86
+ Now, whenever you want to make poems using Shakespeare's lines, you can just use `poefy shakespeare` and it will read from the already created corpora:
44
87
 
45
88
  $ poefy shakespeare sonnet
46
89
  $ poefy shakespeare limerick
47
- $ poefy shakespeare.db villanelle
90
+ $ poefy shakespeare villanelle
48
91
 
49
- The file extension `.db` is assumed for all databases. You can leave it out if you want.
92
+ If you later want to remake the corpus, for example to add new lines, you can use the `-m` option again and the existing corpus will be overwritten.
50
93
 
51
- If you later want to remake the database, for example to add new lines, you can use the `-o` option and the existing database will be overwritten.
94
+ $ cat shakespeare_sonnets.txt shakespeare_plays.txt | poefy shakespeare -m
52
95
 
53
- $ cat shakespeare_sonnets.txt shakespeare_plays.txt | poefy shakespeare -o
96
+ You can use the `-L` or `--list` option to view available corpora.
54
97
 
55
- This database is stored in the same directory as the gem, so it can be accessed by all users on your system. To store a database in a different directory, you can use the `-l` or `--local` option:
98
+ __For SQLite users only:__
99
+ This corpus database file is stored in the same directory as the gem, so it can be accessed by all users on your system. To store a corpus in a different directory, you can use the `-l` or `--local` option:
56
100
 
57
101
  $ poefy -l path/to/eliot.db < eliot.txt
58
102
 
59
103
  You then need to use the `-l` option when generating poems:
60
104
 
61
105
  $ poefy -l path/to/eliot.db rondeau
62
- $ poefy -l path/to/eliot ballade
106
+ $ poefy path/to/eliot.db ballade -l
63
107
  $ cd path/to
64
108
  $ poefy -l eliot.db ballata
65
109
 
66
- You can use the `-h` or `--help` option to view available databases.
110
+ Note that using this option, you *do* need to specify the '.db' file extension of the chosen corpus.
67
111
 
68
112
 
69
113
  #### Option `-f` or `--form`
@@ -239,7 +283,7 @@ To clarify: using the `-p` or `--proper` option will DISABLE this functionality.
239
283
 
240
284
  If the second argument is `rhyme`, then output all lines that rhyme with the word.
241
285
 
242
- This gives a basic look into the database contents.
286
+ This gives a basic look into the contents of the corpus table.
243
287
 
244
288
  ````
245
289
  $ poefy dickinson rhyme confuse
@@ -270,7 +314,7 @@ You can do the same thing for the other keys: `rhyme`, `final_word`, and `syllab
270
314
 
271
315
  #### Special case: poetic form from text file
272
316
 
273
- If you pipe in text and don't use the `-o` option to create a database, then the output will be a poem with the same structure as the file. This can also be accomplished if the second argument is a reference to a text file. So, assuming you have a `lyrics` script that will return song lines for you:
317
+ If you pipe in text and don't use the `-m` option to create a corpus, then the output will be a poem with the same structure as the file. This can also be accomplished if the second argument is a reference to a text file. So, assuming you have a [`lyrics`][1] script that will return song lines for you:
274
318
 
275
319
  $ lyrics 'carly rae jepsen' 'call me maybe' | tee jep.txt | poefy whitman
276
320
  $ poefy whitman < jep.txt
@@ -282,7 +326,7 @@ Any line that is bracketed in `[square]` or `{curly}` braces will be duplicated
282
326
 
283
327
  Also, any indentation will be preserved, assuming 2 spaces per "indent".
284
328
 
285
- Here's an example of a song that can be sung to the same tune as "[I Want to Hold Your Hand][1]", but using lyrics from all Beatles songs:
329
+ Here's an example of a song that can be sung to the same tune as "[I Want to Hold Your Hand][2]", but using lyrics from all Beatles songs:
286
330
 
287
331
  ````
288
332
  $ poefy beatles data/beatles/i_want_to_hold_your_hand.txt
@@ -343,7 +387,8 @@ I'll let me hold your hand You're not the hurting kind
343
387
  I want to hold your hand What goes on in your mind?
344
388
  ````
345
389
 
346
- [1]: https://genius.com/The-beatles-i-want-to-hold-your-hand-lyrics
390
+ [1]: https://github.com/nossidge/lyrics
391
+ [2]: https://genius.com/The-beatles-i-want-to-hold-your-hand-lyrics
347
392
 
348
393
 
349
394
  ### As a Ruby Gem
@@ -352,17 +397,35 @@ To make a poefy database and generate poems from it:
352
397
 
353
398
  ```ruby
354
399
  require 'poefy'
355
- poefy = Poefy::PoefyGen.new('shakespeare')
356
- poefy.make_database('shakespeare_sonnets.txt')
400
+
401
+ # Choose one of the below require lines.
402
+ require 'poefy/pg'
403
+ require 'poefy/sqlite3'
404
+
405
+ # Or you could just run this. It will require the
406
+ # database gem that is specified in 'settings.yml'
407
+ Poefy.require_db
408
+
409
+ # Set up a Poem object using the name of the corpus.
410
+ poefy = Poefy::Poem.new('shakespeare')
411
+
412
+ # Filename is the text file containing the lines.
413
+ # Description is an explanation of the data.
414
+ filename = 'shakespeare_sonnets.txt'
415
+ description = 'The sonnets of Shakespeare'
416
+ poefy.make_database(filename, description)
417
+
418
+ # Close the database link.
419
+ poefy.close
357
420
  ```
358
421
 
359
- `make_database` will accept a filename string, an array of lines, or a long string delimited by newlines.
422
+ `filename` will accept a string path to a file, an array of lines, or a long string delimited by newlines. `description` is optional.
360
423
 
361
424
  You only have to make the database once. And then to generate poems:
362
425
 
363
426
  ```ruby
364
427
  # Different ways to generate sonnets
365
- poefy = Poefy::PoefyGen.new('shakespeare')
428
+ poefy = Poefy::Poem.new('shakespeare')
366
429
  puts poefy.poem ({ rhyme: 'ababcdcdefefgg' })
367
430
  puts poefy.poem ({ rhyme: 'abab cdcd efef gg', indent: '0101 0101 0011 01' })
368
431
  puts poefy.poem ({ form: 'sonnet' })
@@ -375,13 +438,16 @@ puts poefy.poem ({ form: 'sonnet', indent: '01010101001101' })
375
438
  puts poefy.poem ({ form: 'sonnet', proper: false })
376
439
  puts poefy.poem ({ form_from_text: 'how_do_i_love_thee.txt' })
377
440
  puts poefy.poem ({ form_from_text: 'how_do_i_love_thee.txt', syllable: 0 })
441
+ poefy.close
378
442
  ```
379
443
 
444
+ The #poem method requires at least one option of `:rhyme`, `:form`, or `:form_from_text`
445
+
380
446
  All options can be specified at object initialisation, and subsequent poems will use those options as default:
381
447
 
382
448
  ```ruby
383
449
  # Default to use rondeau poetic form, and proper sentence validation
384
- poefy = Poefy::PoefyGen.new('shakespeare', { form: 'rondeau', proper: true })
450
+ poefy = Poefy::Poem.new('shakespeare', { form: 'rondeau', proper: true })
385
451
 
386
452
  # Generate a properly sentenced rondeau
387
453
  puts poefy.poem
@@ -391,6 +457,8 @@ puts poefy.poem ({ proper: false })
391
457
 
392
458
  # Generate a proper rondeau with a certain indentation
393
459
  puts poefy.poem ({ indent: '01012 0012 010112' })
460
+
461
+ poefy.close
394
462
  ```
395
463
 
396
464
 
@@ -405,8 +473,9 @@ transform_hash = {
405
473
  4 => proc { |line, num, poem| line.upcase },
406
474
  12 => proc { |line, num, poem| line.upcase }
407
475
  }
408
- poefy = Poefy::PoefyGen.new 'shakespeare'
476
+ poefy = Poefy::Poem.new 'shakespeare'
409
477
  puts poefy.poem({ form: :sonnet, transform: transform_hash })
478
+ poefy.close
410
479
  ```
411
480
 
412
481
  The key for the hash corresponds to the line of the poem, starting from 1 (not 0). You can use negative keys to specify from the end of the poem. Any key that is not an integer or is out of the array bounds will be ignored.
@@ -415,8 +484,9 @@ If you don't include a hash, then the proc will be applied to each line. So to a
415
484
 
416
485
  ```ruby
417
486
  transform_proc = proc { |line, num, poem| "#{num.to_s.rjust(2)} #{line}" }
418
- poefy = Poefy::PoefyGen.new 'shakespeare'
487
+ poefy = Poefy::Poem.new 'shakespeare'
419
488
  puts poefy.poem({ form: :sonnet, transform: transform_proc })
489
+ poefy.close
420
490
  ```
421
491
 
422
492
  The proc arguments `|line, num, poem|` are: the text of the line that is being replaced, the number of the line, and the full poem array as it was before any transformations had occurred.
@@ -424,6 +494,84 @@ The proc arguments `|line, num, poem|` are: the text of the line that is being r
424
494
  The transformations are implemented after the poem has been generated, but before the `indent` has occurred.
425
495
 
426
496
 
497
+ #### Corpus internals
498
+
499
+ The `Poefy::Poem.poem` method will do the work of creating a poem for you, but the object also exposes more information about the corpus, if you need it. This is done through the `Poefy::Poem.corpus` object.
500
+
501
+ ```ruby
502
+ # If the corpus database already exists:
503
+ poefy = Poefy::Poem.new('shakespeare')
504
+ puts poefy.corpus.type # "sqlite3" or "pg"
505
+ puts poefy.corpus.name # "shakespeare"
506
+ puts poefy.corpus.count # 2137
507
+ puts poefy.corpus.exists? # true
508
+
509
+ # If the corpus has not been generated yet:
510
+ poefy = Poefy::Poem.new('plath')
511
+ puts poefy.corpus.type # "sqlite3" or "pg"
512
+ puts poefy.corpus.name # "plath"
513
+ puts poefy.corpus.count # 0
514
+ puts poefy.corpus.exists? # false
515
+ ```
516
+
517
+ To view or change the description of the corpus.
518
+
519
+ ```ruby
520
+ poefy = Poefy::Poem.new('shakespeare')
521
+ puts 'Initial description: ' + poefy.corpus.desc
522
+ # Initial description: Shakespeare's sonnets
523
+
524
+ poefy.corpus.desc = 'a brand new string'
525
+ puts 'Updated description: ' + poefy.corpus.desc
526
+ # Updated description: a brand new string
527
+ ```
528
+
529
+ There's also a public interface to find rhyming lines within the corpus. Let's say we need to find 6 lines with the same rhyme. First, we will get an array of all rhyme keys that have at least 6 distinct final words. Then select one rhyme at random. Use that rhyme to find all lines that have that rhyme key, and remove lines with duplicate last words (so that we don't rhyme e.g. "tree" with "tree"). Then grab a sample 6 lines from that array.
530
+
531
+ ```ruby
532
+ poefy = Poefy::Poem.new('shakespeare')
533
+ line_count = 6
534
+
535
+ rhymes = poefy.corpus.rhymes_by_count(line_count)
536
+ rhyme = rhymes.sample['rhyme']
537
+ lines = poefy.corpus.lines_by_rhyme(rhyme)
538
+ lines = lines.map{ |i| i['line'] }.shuffle
539
+ lines.uniq!{ |i| i.to_phrase.last_word.downcase }
540
+ puts lines.sample(line_count)
541
+
542
+ # Mine eye and heart are at a mortal war,
543
+ # Like as the waves make towards the pebbled shore,
544
+ # Let those whom nature hath not made for store,
545
+ # All mine was thine, before thou hadst this more.
546
+ # O! though I love what others do abhor,
547
+ # To show false Art what beauty was of yore.
548
+ ```
549
+
550
+ You can also specify a range for the lines' syllable counts. Just use a hash with keys ':min' and ':max' as the second argument.
551
+
552
+ ```ruby
553
+ poefy = Poefy::Poem.new('whitman')
554
+ line_count = 6
555
+ syllables = {min: 8, max: 8}
556
+
557
+ rhymes = poefy.corpus.rhymes_by_count(line_count, syllables)
558
+ rhyme = rhymes.sample['rhyme']
559
+ lines = poefy.corpus.lines_by_rhyme(rhyme, syllables)
560
+ lines = lines.map{ |i| i['line'] }.shuffle
561
+ lines.uniq!{ |i| i.to_phrase.last_word.downcase }
562
+ puts lines.sample(line_count)
563
+
564
+ # As I wended the shores I know,
565
+ # Rhone, and the Guadalquiver flow,
566
+ # Scooting obliquely high and low.
567
+ # O heart-sick days! O nights of woe!
568
+ # Ceaseless she paces to and fro,
569
+ # To be lost if it must be so!
570
+ ```
571
+
572
+ `#rhymes_by_count` and `#lines_by_rhyme` are the only stored procedures that return corpus lines. All the other filtering and line arrangement is done based on the records returned by these two methods.
573
+
574
+
427
575
  ## Some tips
428
576
 
429
577
  ### Make a database from a delimited file
@@ -432,26 +580,26 @@ Databases are created using data piped into poefy, so you can do any pre-process
432
580
 
433
581
  Use awk to get final field from tab delimited IRC logs.
434
582
 
435
- $ awk -F$'\t' '{print $NF}' irc_log_20170413.txt | poefy -o irc
583
+ $ awk -F$'\t' '{print $NF}' irc_log_20170908.txt | poefy -m irc
436
584
 
437
585
 
438
586
  ### Make a database, ignoring short lines
439
587
 
440
588
  Use sed to filter out lines that are too short:
441
589
 
442
- $ sed -r '/^.{,20}$/d' st_therese_of_lisieux.txt | poefy -o therese
590
+ $ sed -r '/^.{,20}$/d' st_therese_of_lisieux.txt | poefy -m therese
443
591
 
444
592
 
445
593
  ### Make a database, ignoring uppercase lines
446
594
 
447
595
  Use sed to filter out lines that do not contain lowercase letters. For example, the sonnets file contains lines with the number of the sonnet, e.g. "CXLVII."
448
596
 
449
- $ sed -r 'sed '/[a-z]/!d' shakespeare_sonnets.txt | poefy -o shakespeare
597
+ $ sed -r 'sed '/[a-z]/!d' shakespeare_sonnets.txt | poefy -m shakespeare
450
598
 
451
599
 
452
600
  ### Problem: it won't output lines that I know are valid
453
601
 
454
- This code uses a gem called `wordfilter` that will automatically filter out lines that contain [grotty words](https://github.com/dariusk/wordfilter/blob/master/lib/badwords.json). If you really definitely truly don't want to exclude a certain word, you can remove them from the blacklist. For example, if your input lines are from a dissertation on the dance styles of the ska and reggae music scenes, you can call:
602
+ This code uses a gem called `wordfilter` that will automatically filter out lines that contain [grotty words](https://github.com/dariusk/wordfilter/blob/master/lib/badwords.json). If you really definitely truly don't want to exclude a certain word, you can remove that word from the blacklist. For example, if your input lines are from a dissertation on the dance styles of the ska and reggae music scenes, in your Ruby code you can call:
455
603
 
456
604
  ```ruby
457
605
  Wordfilter.remove_word('skank')
data/bin/poefy CHANGED
@@ -2,20 +2,34 @@
2
2
  # Encoding: UTF-8
3
3
 
4
4
  ################################################################################
5
- # Use Poefy::PoefyGen to make a poem from the command line.
5
+ # Use Poefy::Poem to make a poem from the command line.
6
6
  ################################################################################
7
7
 
8
8
  require 'optparse'
9
9
 
10
10
  require_relative '../lib/poefy.rb'
11
11
 
12
+ Poefy.console = true
13
+ Poefy.require_db
14
+
15
+ ################################################################################
16
+
17
+ # List the corpora & descriptions in a nice table format.
18
+ def corpora
19
+ output = Poefy.corpora_with_desc
20
+ width = output.keys.max_by(&:length).length
21
+ output.map do |key, value|
22
+ sprintf "%-#{width}s %s", key, value
23
+ end
24
+ end
25
+
12
26
  ################################################################################
13
27
 
14
28
  def parse_options
15
- options = { console: true }
29
+ options = {}
16
30
 
17
31
  # Set up variables used later.
18
- forms = Poefy::PoeticForms::POETIC_FORMS.keys.reject { |i| i == :default }
32
+ forms = Poefy.poetic_forms
19
33
  forms_by_4 = forms.each_slice(4).to_a.map { |i| i.join ', ' }
20
34
  rhyme_docs = " This is the most important argument.
21
35
  All other form strings are based on this.
@@ -39,20 +53,18 @@ def parse_options
39
53
  Paul Thompson - nossidge@gmail.com
40
54
  ].gsub(' ',' ')
41
55
 
42
- usage = %[Usage: poefy shakespeare < shakespeare_sonnets.txt
56
+ usage = %[Usage: poefy shakespeare -m < shakespeare_sonnets.txt
57
+ poefy shakespeare -d "The sonnets of Shakespeare"
43
58
  poefy shakespeare sonnet
44
59
  poefy spoke haiku
45
60
  poefy therese -r 'abab cdcd efef gg' -i '0101 0101 0011 01'
46
61
  poefy whitman -r 'A1bA2 abA1 abA2 abA1 abA2 abA1A2'
62
+ poefy -Lc
47
63
  ].gsub(' ',' ')
48
64
 
49
- databases = (Poefy.all_databases - ['test'])
50
- .each_slice(4).to_a
51
- .map { |i| i.join ', ' }
52
- .join("\n" + ' ' * 21)
53
- databases = 'Databases available: ' + databases
65
+ list = 'Corpora: ' + corpora.join("\n ")
54
66
 
55
- opts.banner = program_info + "\n" + usage + "\n" + databases + "\n\n"
67
+ opts.banner = program_info + "\n" + usage + "\n" + list + "\n\n"
56
68
 
57
69
  # These will be further validated within the class.
58
70
  opts.on('-f', '--form STRING',
@@ -62,7 +74,7 @@ def parse_options
62
74
  ' ' * 39 + forms_by_4.join("\n" + ' ' * 39)) do |s|
63
75
  options[:form] = s
64
76
  end
65
- opts.on('-r', '--rhyme STRING', "See big block of text below") do |s|
77
+ opts.on('-r', '--rhyme STRING', "(See 'Description of rhyme string' below)") do |s|
66
78
  options[:rhyme] = s
67
79
  end
68
80
  opts.on('-i', '--indent STRING', "Indentation of each line") do |s|
@@ -103,18 +115,52 @@ def parse_options
103
115
  options[:number] = n.to_i
104
116
  end
105
117
 
106
- # Database options.
118
+ # Corpus options.
107
119
  opts.separator nil
108
- opts.on('-o', '--overwrite',
109
- "Overwrite existing database with new input") do
110
- options[:overwrite] = true
120
+ opts.on('-m', '--make [STRING]',
121
+ "Make new or overwrite existing corpus with piped input\n" + ' ' * 39 +
122
+ "Argument is a description of the corpus") do |s|
123
+ options[:make_corpus] = true
124
+ options[:corpus_desc] = s
125
+ end
126
+ opts.on('-d', '--desc STRING',
127
+ "Overwrite the description of the corpus") do |s|
128
+ options[:corpus_desc] = s
111
129
  end
112
130
  opts.on('-l', '--local',
113
- "Default is to use database files from /data/\n" + ' ' * 39 +
114
- "With this option, use files from elsewhere") do
131
+ "(SQLite only) Default is to use database files from /data/\n" + ' ' * 39 +
132
+ "With this option, paths are relative to working directory") do
115
133
  options[:local] = true
116
134
  end
117
135
 
136
+ # Database internals.
137
+ opts.separator nil
138
+ opts.on('-L', '--list [C|D]',
139
+ "List all the installed corpora\n" + ' ' * 39 +
140
+ "Append 'c' or 'd' to list just the corpora or descriptions") do |s|
141
+ s ||= ' '
142
+ if s[0].casecmp('c').zero?
143
+ puts Poefy.corpora
144
+ elsif s[0].casecmp('d').zero?
145
+ puts Poefy.corpora_with_desc.values
146
+ else
147
+ puts corpora
148
+ end
149
+ exit 0
150
+ end
151
+ opts.on('-D', '--database [pg|sqlite3]',
152
+ "Display the database implementation setting\n" + ' ' * 39 +
153
+ "Append 'pg' or 'sqlite3' to change programs") do |s|
154
+ s ||= ' '
155
+ if s[0].casecmp('p').zero?
156
+ Poefy.database_type = 'pg'
157
+ elsif s[0].casecmp('s').zero?
158
+ Poefy.database_type = 'sqlite3'
159
+ end
160
+ puts Poefy.database_type
161
+ exit 0
162
+ end
163
+
118
164
  # Help output.
119
165
  opts.separator nil
120
166
  opts.on('-h', '--help', 'Display this help screen' ) do
@@ -152,67 +198,53 @@ options = parse_options
152
198
  # Read data lines from STDIN.
153
199
  data = (not STDIN.tty? and not STDIN.closed?) ? STDIN.read : nil
154
200
 
155
- # Database is the first argument.
201
+ # Corpus name is the first argument.
156
202
  first_arg = ARGV.first
157
203
  if first_arg.nil?
158
- STDERR.puts "ERROR: Please specify a database to read from / to"
204
+ STDERR.puts "ERROR: Please specify a corpus name to read from/to"
159
205
  exit 1
160
206
  end
161
207
 
162
- # If the first argument is 'make_dbs', then make
163
- # databases from the included text files.
164
- if first_arg == 'make_dbs'
165
- path = File.expand_path('../../data', __FILE__)
166
-
167
- input = `sed '/[a-z]/!d' #{path}/shakespeare_sonnets.txt`
168
- poefy = Poefy::PoefyGen.new 'shakespeare'
169
- poefy.make_database input, false
170
-
171
- input = `sed '/[a-z]/!d' #{path}/st_therese_of_lisieux.txt`
172
- poefy = Poefy::PoefyGen.new 'therese'
173
- poefy.make_database input, false
174
-
175
- input = `sed '/[a-z]/!d' #{path}/whitman_leaves.txt`
176
- poefy = Poefy::PoefyGen.new 'whitman'
177
- poefy.make_database input, false
178
-
179
- input = `sed '/[a-z]/!d' #{path}/emily_dickinson.txt`
180
- poefy = Poefy::PoefyGen.new 'dickinson'
181
- poefy.make_database input, false
182
-
183
- input = `sed '/[a-z]/!d' #{path}/english_as_she_is_spoke.txt`
184
- poefy = Poefy::PoefyGen.new 'spoke'
185
- poefy.make_database input, false
186
-
187
- exit 0
188
- end
189
-
190
208
  # Poetic form name is the second argument, if it exists.
191
209
  second_arg = (ARGV.length > 1) ? ARGV[1] : ''
192
210
  options[:form] = second_arg if second_arg != ''
193
211
 
194
- # If we need to make a database.
195
- # Exit the program after database is generated.
196
- if options[:overwrite]
197
- poefy = Poefy::PoefyGen.new first_arg
212
+ # If we need to make a corpus.
213
+ # Exit the program after corpus is generated.
214
+ if options[:make_corpus]
215
+ poefy = Poefy::Poem.new first_arg
198
216
  if data
199
- poefy.make_database data, true
217
+ poefy.make_database data, options[:corpus_desc], true
200
218
  poefy.close
201
219
  exit 0
202
220
  else
203
- STDERR.puts 'ERROR: Need text input to generate a database'
221
+ STDERR.puts 'ERROR: Need text input to generate a corpus'
204
222
  STDERR.puts ' Please pipe some data into the program'
205
223
  exit 1
206
224
  end
207
225
  end
208
226
 
227
+ # If we need to update a corpus description.
228
+ # Exit the program after corpus is generated.
229
+ if options[:corpus_desc]
230
+ poefy = Poefy::Poem.new first_arg
231
+ begin
232
+ poefy.corpus.desc = options[:corpus_desc]
233
+ poefy.close
234
+ exit 0
235
+ rescue
236
+ STDERR.puts "ERROR: Corpus '#{first_arg}' does not yet exist"
237
+ exit 1
238
+ end
239
+ end
240
+
209
241
  # If the second argument is 'rhyme', then output all
210
242
  # lines that rhyme with the word.
211
243
  if second_arg == 'rhyme'
212
- poefy = Poefy::PoefyGen.new first_arg
244
+ poefy = Poefy::Poem.new first_arg
213
245
  third_arg = (ARGV.length > 2) ? ARGV[2] : nil
214
246
  fourth_arg = (ARGV.length > 3) ? ARGV[3] : nil
215
- puts poefy.rhymes(third_arg, fourth_arg)
247
+ puts poefy.corpus.rhymes(third_arg, fourth_arg)
216
248
  exit 0
217
249
  end
218
250
 
@@ -223,7 +255,7 @@ if data or File.exists?(second_arg)
223
255
  end
224
256
 
225
257
  # Create poefy object using the options.
226
- poefy = Poefy::PoefyGen.new first_arg, options
258
+ poefy = Poefy::Poem.new first_arg, options
227
259
 
228
260
  # Make the correct number of poems, and output them.
229
261
  number = options[:number] || 1