oulipo 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +54 -35
- data/lib/oulipo/enhanced_string.rb +5 -0
- data/lib/oulipo/string_em_up.rb +3 -0
- data/lib/oulipo/string_extensions.rb +86 -0
- data/lib/oulipo.rb +10 -68
- data/oulipo.gemspec +1 -1
- data/spec/alliteration_spec.rb +13 -11
- data/spec/analysis_spec.rb +1 -2
- data/spec/chaterisms_spec.rb +10 -9
- data/spec/lipograms_spec.rb +11 -9
- data/spec/palindromes_spec.rb +6 -4
- data/spec/spec_helper.rb +13 -1
- data/spec/substitution_spec.rb +11 -6
- data/spec/univocalisms_spec.rb +6 -4
- metadata +22 -29
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -8,7 +8,7 @@ It's still young, and very much liable to change.
|
|
8
8
|
|
9
9
|
The real [Oulipo](http://en.wikipedia.org/wiki/Oulipo) is a gathering of writers and mathmeticians who seek to create works using constrained writing techniques.
|
10
10
|
|
11
|
-
Install with `gem install oulipo
|
11
|
+
Install with `gem install oulipo` and `require 'oulipo'` as needed.
|
12
12
|
|
13
13
|
## Lipograms and Pangrams
|
14
14
|
|
@@ -40,37 +40,6 @@ sentence = 'Big fjords vex quick waltz nymph.'
|
|
40
40
|
Oulipo.pangram?(sentence) # => true
|
41
41
|
```
|
42
42
|
|
43
|
-
## N+7
|
44
|
-
|
45
|
-
In N+7 (sometimes known as S+7), each noun in a text is replaced with the noun seven entries after it in a dictionary.
|
46
|
-
|
47
|
-
```ruby
|
48
|
-
dictionary = Oulipo::WordList.load('big_list_of_nouns.txt')
|
49
|
-
|
50
|
-
play = <<-SHAKESPEARE
|
51
|
-
|
52
|
-
What, jealous Oberon! Fairies, skip hence:
|
53
|
-
I have forsworn his bed and company.
|
54
|
-
|
55
|
-
SHAKESPEARE
|
56
|
-
|
57
|
-
Oulipo.n_plus(7, play, dictionary) # => "What, jealous Oberon! Fallacies, skulk hence:
|
58
|
-
# I have forsworn his bedroom and compensation."
|
59
|
-
|
60
|
-
```
|
61
|
-
|
62
|
-
Oulipo includes a handy `WordList` class for reading one-word-per-line dictionary files, but a dictionary can be any object that responds to `index(word)`, `length`, and `[index]`.
|
63
|
-
|
64
|
-
```ruby
|
65
|
-
dictionary = %w{ iron gild mine gold ore paint cast lily }
|
66
|
-
|
67
|
-
king_john = 'To gild refined gold, to paint the lily'
|
68
|
-
|
69
|
-
Oulipo.n_plus(1, king_john, dictionary) # => 'To mine refined ore, to cast the iron'
|
70
|
-
```
|
71
|
-
|
72
|
-
See also: Substitution.
|
73
|
-
|
74
43
|
## Univocalims
|
75
44
|
|
76
45
|
A univocalism is a poem written using only one type of vowel.
|
@@ -132,8 +101,56 @@ Normal alliteration's a little harsh, so you can give it a threshold, too.
|
|
132
101
|
phrase = 'quick queens quibble over quails'
|
133
102
|
|
134
103
|
Oulipo.alliterativity(phrase) # => 0.8 (4/5 words start with 'q')
|
135
|
-
Oulipo.
|
136
|
-
Oulipo.
|
104
|
+
Oulipo.alliteration?(phrase, :threshold => 0.7) # => true
|
105
|
+
Oulipo.alliteration?(phrase, :threshold => 0.9) # => false
|
106
|
+
```
|
107
|
+
|
108
|
+
## N+7
|
109
|
+
|
110
|
+
In N+7 (sometimes known as S+7), each noun in a text is replaced with the noun seven entries after it in a dictionary.
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
dictionary = Oulipo::WordList.load('big_list_of_nouns.txt')
|
114
|
+
|
115
|
+
play = <<-SHAKESPEARE
|
116
|
+
|
117
|
+
What, jealous Oberon! Fairies, skip hence:
|
118
|
+
I have forsworn his bed and company.
|
119
|
+
|
120
|
+
SHAKESPEARE
|
121
|
+
|
122
|
+
Oulipo.n_plus(7, play, dictionary) # => "What, jealous Oberon! Fallacies, skulk hence:
|
123
|
+
# I have forsworn his bedroom and compensation."
|
124
|
+
|
125
|
+
```
|
126
|
+
|
127
|
+
Oulipo includes a handy `WordList` class for reading one-word-per-line dictionary files, but a dictionary can be any object that responds to `index(word)`, `length`, and `[index]`.
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
dictionary = %w{ iron gild mine gold ore paint cast lily }
|
131
|
+
|
132
|
+
king_john = 'To gild refined gold, to paint the lily'
|
133
|
+
|
134
|
+
Oulipo.n_plus(1, king_john, dictionary) # => 'To mine refined ore, to cast the iron'
|
135
|
+
```
|
136
|
+
|
137
|
+
## Extending String
|
138
|
+
|
139
|
+
You can optionally extend `String`, if you need to.
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
require 'oulipo/string_em_up'
|
143
|
+
|
144
|
+
"Sator arepo tenet opera rotas".palindrome? # => true
|
145
|
+
"Waltz, bad nymph, for quick jigs vex!".pangram? # => true
|
146
|
+
'To gild refined gold'.n_plus(7, nouns) # ... as above
|
147
|
+
```
|
148
|
+
|
149
|
+
If you'd like to use the neat short-hand, but don't want to touch `String`, you might want to use an `EnhancedString`.
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
palindrome = Oulipo::EnhancedString.new("Sator arepo tenet opera rotas")
|
153
|
+
palindrome.lipogram? # => true
|
137
154
|
```
|
138
155
|
|
139
156
|
## Analysis
|
@@ -152,6 +169,8 @@ analysis = Oulipo::Analysis.new(line, word_sets)
|
|
152
169
|
|
153
170
|
analysis.identified(:nouns) # => ['rose', 'name']
|
154
171
|
analysis.identified(:adjectives) # => ['sweet']
|
172
|
+
|
173
|
+
analysis.deconstruction # => ["A ", ["rose", :nouns], " by any other ", ["name", :nouns], " would smell as ", ["sweet", :adjectives]]
|
155
174
|
```
|
156
175
|
|
157
176
|
## Substitution
|
@@ -167,4 +186,4 @@ substitutor.replace(:nouns).increment(1) # => "A bear by any other rose would sm
|
|
167
186
|
|
168
187
|
---
|
169
188
|
|
170
|
-
|
189
|
+
Pete Nicholls ([@Aupajo](http://twitter.com/Aupajo))
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Oulipo
|
2
|
+
module StringExtensions
|
3
|
+
ALPHABET = 'a'..'z'
|
4
|
+
VOWELS = %w{ a e i o u }
|
5
|
+
|
6
|
+
# Whether the string uses alliteration or not.
|
7
|
+
# Accepts a :threshold option for determining whether the string
|
8
|
+
# uses sufficient alliteration (see #aliterativity)
|
9
|
+
def alliteration?(options = {})
|
10
|
+
threshold = options.delete(:threshold) || 1
|
11
|
+
self.alliterativity >= threshold
|
12
|
+
end
|
13
|
+
|
14
|
+
# A score between 0 and 1 representing the level of alliteration
|
15
|
+
def alliterativity
|
16
|
+
words = self.downcase.gsub(/[^a-z\s]/, '').split
|
17
|
+
leading_letters = words.map(&:chr)
|
18
|
+
|
19
|
+
# { 'a' => 3, 'b' => 1, ... }
|
20
|
+
leading_letter_counts = leading_letters.inject({}) do |result, letter|
|
21
|
+
result[letter] ||= 0
|
22
|
+
result[letter] += 1
|
23
|
+
result
|
24
|
+
end
|
25
|
+
|
26
|
+
most_used_count = leading_letter_counts.max_by { |kv| kv.last }.pop
|
27
|
+
most_used_count.to_f / words.length
|
28
|
+
end
|
29
|
+
|
30
|
+
# The same letters backwards as forwards
|
31
|
+
def palindrome?
|
32
|
+
letter_sequence = self.downcase.gsub(/[^a-z]/, '')
|
33
|
+
letter_sequence.reverse == letter_sequence
|
34
|
+
end
|
35
|
+
|
36
|
+
# Replace the words in the word list with the word n places after it
|
37
|
+
def n_plus(places, word_list)
|
38
|
+
analysis = Analysis.new(self, :nouns => word_list)
|
39
|
+
substitutor = Substitutor.new(analysis)
|
40
|
+
substitutor.replace(:nouns).increment(places)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns true if each word is one letter larger than the previous
|
44
|
+
def snowball?
|
45
|
+
words = self.split
|
46
|
+
self.chaterism? && words.first.length < words.last.length
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns true if only one vowel is used
|
50
|
+
def univocalism?
|
51
|
+
present_letters = self.downcase.split('').uniq
|
52
|
+
(VOWELS - present_letters).length == 4
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns true if the string is a sequence of words in each of which is one letter larger than the
|
56
|
+
# previous, or each word in the sequence is one letter less than the previous
|
57
|
+
def chaterism?
|
58
|
+
words = self.gsub(/[^a-z\s]/i, '').split
|
59
|
+
|
60
|
+
# Find the direction we're traveling
|
61
|
+
flen, llen = words.first.length, words.last.length
|
62
|
+
direction = flen > llen ? :downto : :upto
|
63
|
+
|
64
|
+
# Compare the pattern of word lengths against a range-turned-array of expected word lengths
|
65
|
+
words.map(&:length) == flen.send(direction, llen).to_a
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns an array of letters that are absent
|
69
|
+
def absent_letters
|
70
|
+
present_letters = self.downcase.split('').uniq
|
71
|
+
missing_letters = ALPHABET.to_a - present_letters
|
72
|
+
missing_letters.empty? ? nil : missing_letters
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns true if all letters of the alphabet are used
|
76
|
+
def pangram?
|
77
|
+
self.absent_letters.nil?
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns true if not all of the letters of the alphabet are used
|
81
|
+
def lipogram?
|
82
|
+
!self.pangram?
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
data/lib/oulipo.rb
CHANGED
@@ -1,79 +1,21 @@
|
|
1
1
|
require 'oulipo/word_list'
|
2
|
+
require 'oulipo/string_extensions'
|
3
|
+
require 'oulipo/enhanced_string'
|
2
4
|
require 'oulipo/analysis'
|
3
5
|
require 'oulipo/substitutor'
|
4
6
|
|
5
7
|
module Oulipo
|
6
|
-
ALPHABET = 'a'..'z'
|
7
|
-
VOWELS = %w{ a e i o u }
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
# A pangram uses all letters
|
16
|
-
def self.pangram?(work)
|
17
|
-
self.absent_letters(work).nil?
|
18
|
-
end
|
19
|
-
|
20
|
-
# A lipogram has missing letters
|
21
|
-
def self.lipogram?(work)
|
22
|
-
!self.pangram?(work)
|
23
|
-
end
|
24
|
-
|
25
|
-
# In a chaterism, each successive word is larger than the last or vice versa
|
26
|
-
def self.chaterism?(poem)
|
27
|
-
# Discard the punctuation, split into words
|
28
|
-
words = poem.gsub(/[^a-z\s]/i, '').split
|
29
|
-
|
30
|
-
# Find the direction we're traveling
|
31
|
-
flen, llen = words.first.length, words.last.length
|
32
|
-
direction = flen > llen ? :downto : :upto
|
33
|
-
|
34
|
-
# "The tree sings".map(&:length) # => [3, 4, 5]
|
35
|
-
# [3, 4, 5] == 3.upto(5).to_a # => true
|
36
|
-
words.map(&:length) == flen.send(direction, llen).to_a
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.univocalism?(poem)
|
40
|
-
present_letters = poem.downcase.split('').uniq
|
41
|
-
(VOWELS - present_letters).length == 4
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.snowball?(poem)
|
45
|
-
words = poem.split
|
46
|
-
self.chaterism?(poem) && words.first.length < words.last.length
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.palindrome?(phrase)
|
50
|
-
sequence = phrase.downcase.gsub(/[^a-z]/, '')
|
51
|
-
sequence.reverse == sequence
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.alliteration?(phrase, options = {})
|
55
|
-
threshold = options.delete(:threshold) || 1
|
56
|
-
self.alliterativity(phrase) >= threshold
|
57
|
-
end
|
58
|
-
|
59
|
-
# Calculate an alliteration score
|
60
|
-
def self.alliterativity(phrase)
|
61
|
-
words = phrase.downcase.gsub(/[^a-z\s]/, '').split
|
62
|
-
leading_letters = words.map(&:chr)
|
63
|
-
|
64
|
-
leading_letter_counts = leading_letters.inject({}) do |result, letter|
|
65
|
-
result[letter] ||= 0
|
66
|
-
result[letter] += 1
|
67
|
-
result
|
68
|
-
end
|
69
|
-
|
70
|
-
most_used_count = leading_letter_counts.max_by { |kv| kv.last }.pop
|
71
|
-
most_used_count.to_f / words.length
|
9
|
+
[:absent_letters, :pangram?, :lipogram?, :chaterism?,
|
10
|
+
:univocalism?, :snowball?, :palindrome?, :alliteration?,
|
11
|
+
:alliterativity].each do |method|
|
12
|
+
define_singleton_method(method.to_sym) do |*args|
|
13
|
+
EnhancedString.new(args.shift).send(method.to_sym, *args)
|
14
|
+
end
|
72
15
|
end
|
73
16
|
|
17
|
+
# Replace the word nth places ahead in the word_list
|
74
18
|
def self.n_plus(places, text, word_list)
|
75
|
-
|
76
|
-
substitutor = Substitutor.new(analysis)
|
77
|
-
substitutor.replace(:nouns).increment(places)
|
19
|
+
EnhancedString.new(text).n_plus(places, word_list)
|
78
20
|
end
|
79
21
|
end
|
data/oulipo.gemspec
CHANGED
data/spec/alliteration_spec.rb
CHANGED
@@ -1,26 +1,28 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'oulipo/string_em_up'
|
2
3
|
|
3
4
|
describe "alliteration" do
|
4
5
|
|
5
|
-
let(:performer) { Oulipo }
|
6
|
-
|
7
6
|
let(:pure_alliteration) { 'spec step succeeds speedily' }
|
8
7
|
let(:mostly_alliterative) { 'quick queens quibble over quails' }
|
9
8
|
|
10
9
|
it "detects pure alliteration" do
|
11
|
-
|
10
|
+
pure_alliteration.should be_alliteration
|
12
11
|
end
|
13
|
-
|
12
|
+
|
14
13
|
it "tells us the alliterativity of a phrase" do
|
15
|
-
|
16
|
-
|
14
|
+
pure_alliteration.alliterativity.should == 1.0
|
15
|
+
mostly_alliterative.alliterativity.should == 0.8
|
17
16
|
end
|
18
|
-
|
17
|
+
|
19
18
|
it "detects alliteration with a threshold" do
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
mostly_alliterative.should_not be_alliteration
|
20
|
+
mostly_alliterative.should be_alliteration(:threshold => 0.7)
|
21
|
+
mostly_alliterative.should be_alliteration(:threshold => 0.8)
|
22
|
+
mostly_alliterative.should_not be_alliteration(:threshold => 0.9)
|
24
23
|
end
|
25
24
|
|
25
|
+
it "is accessible via Oulipo" do
|
26
|
+
Oulipo.should forward_to_enhanced_string(:alliterativity, :alliteration?)
|
27
|
+
end
|
26
28
|
end
|
data/spec/analysis_spec.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Oulipo::Analysis do
|
4
|
-
include Oulipo
|
5
4
|
|
6
5
|
let(:folksong) { "O'er the moor and among the heather" }
|
7
6
|
|
8
7
|
let(:word_lists) { { :nouns => %w{ moor heather },
|
9
8
|
:prepositions => %w{ among } } }
|
10
9
|
|
11
|
-
let(:analysis) { Analysis.new(folksong, word_lists) }
|
10
|
+
let(:analysis) { Oulipo::Analysis.new(folksong, word_lists) }
|
12
11
|
|
13
12
|
it "can identify words" do
|
14
13
|
analysis.identified.sort.should == %w{ among heather moor }
|
data/spec/chaterisms_spec.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'oulipo/string_em_up'
|
2
3
|
|
3
4
|
describe "chaterisms" do
|
4
5
|
|
5
|
-
# For easy switching
|
6
|
-
let(:performer) { Oulipo }
|
7
|
-
|
8
6
|
let(:snowball_poem) do
|
9
7
|
<<-POEM
|
10
8
|
The
|
@@ -33,15 +31,18 @@ describe "chaterisms" do
|
|
33
31
|
}
|
34
32
|
|
35
33
|
it "can detect both diminishing and growing chaterisms" do
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
snowball_poem.should be_chaterism
|
35
|
+
diminishing_poem.should be_chaterism
|
36
|
+
regular_poem.should_not be_chaterism
|
39
37
|
end
|
40
38
|
|
41
39
|
it "detects a snowball poem" do
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
snowball_poem.should be_snowball
|
41
|
+
diminishing_poem.should_not be_snowball
|
42
|
+
regular_poem.should_not be_snowball
|
45
43
|
end
|
46
44
|
|
45
|
+
it "is accessible via Oulipo" do
|
46
|
+
Oulipo.should forward_to_enhanced_string(:chaterism?, :snowball?)
|
47
|
+
end
|
47
48
|
end
|
data/spec/lipograms_spec.rb
CHANGED
@@ -1,24 +1,26 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'oulipo/string_em_up'
|
2
3
|
|
3
4
|
describe "lipograms and pangrams" do
|
4
5
|
|
5
|
-
# Easy to switch class, if refactored
|
6
|
-
let(:performer) { Oulipo }
|
7
|
-
|
8
6
|
let(:pangram) { 'The quick brown fox jumps over a lazy god' }
|
9
7
|
let(:lipogram) { 'The quick grey fox jumps over lazy gods' }
|
10
8
|
|
11
9
|
it "shows absent letters" do
|
12
|
-
|
13
|
-
|
10
|
+
pangram.absent_letters.should be_nil
|
11
|
+
lipogram.absent_letters.should == %w{ b n w }
|
14
12
|
end
|
15
13
|
|
16
14
|
it "can tell a pangram from a lipogram" do
|
17
|
-
|
18
|
-
|
15
|
+
lipogram.should be_lipogram
|
16
|
+
pangram.should_not be_lipogram
|
19
17
|
|
20
|
-
|
21
|
-
|
18
|
+
lipogram.should_not be_pangram
|
19
|
+
pangram.should be_pangram
|
20
|
+
end
|
21
|
+
|
22
|
+
it "is accessible via Oulipo" do
|
23
|
+
Oulipo.should forward_to_enhanced_string(:lipogram?, :pangram?)
|
22
24
|
end
|
23
25
|
|
24
26
|
end
|
data/spec/palindromes_spec.rb
CHANGED
@@ -2,11 +2,13 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe "palindromes" do
|
4
4
|
|
5
|
-
let(:performer) { Oulipo }
|
6
|
-
|
7
5
|
it "detects palindromes" do
|
8
|
-
|
9
|
-
|
6
|
+
'Mr. Owl ate my metal worm'.should be_palindrome
|
7
|
+
'Carelessness is a dish best served drunk'.should_not be_palindrome
|
8
|
+
end
|
9
|
+
|
10
|
+
it "is accessible via Oulipo" do
|
11
|
+
Oulipo.should forward_to_enhanced_string(:palindrome?)
|
10
12
|
end
|
11
13
|
|
12
14
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,4 +2,16 @@ require 'bundler'
|
|
2
2
|
Bundler.setup(:default, :test)
|
3
3
|
|
4
4
|
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
-
require 'oulipo'
|
5
|
+
require 'oulipo'
|
6
|
+
|
7
|
+
RSpec::Matchers.define :forward_to_enhanced_string do |*forwarded_methods|
|
8
|
+
match do |oulipo|
|
9
|
+
stubs = forwarded_methods.inject({}) { |stubs, method| stubs.merge(method => :forwarded) }
|
10
|
+
enhanced_string = mock(:enhanced_string, stubs)
|
11
|
+
Oulipo::EnhancedString.should_receive(:new).with('a phrase').at_least(:once).and_return(enhanced_string)
|
12
|
+
|
13
|
+
forwarded_methods.each do |method|
|
14
|
+
oulipo.send(method, 'a phrase').should == :forwarded
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/spec/substitution_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'oulipo/string_em_up'
|
2
3
|
|
3
4
|
describe "substitution" do
|
4
5
|
|
@@ -10,8 +11,6 @@ describe "substitution" do
|
|
10
11
|
Oulipo::Substitutor.new analysis_with(*args)
|
11
12
|
end
|
12
13
|
|
13
|
-
let(:performer) { Oulipo }
|
14
|
-
|
15
14
|
let(:phrase) { 'The bear ate the badger' }
|
16
15
|
let(:noun_list) { %w{ badger bat bear } }
|
17
16
|
let(:substitutor) { substitutor_with(phrase, :nouns => noun_list) }
|
@@ -25,11 +24,17 @@ describe "substitution" do
|
|
25
24
|
it "raises an error if increment is called before replace" do
|
26
25
|
lambda { substitutor.increment(3) }.should raise_error
|
27
26
|
end
|
28
|
-
|
27
|
+
|
29
28
|
it "can be accessed from Oulipo with n_plus" do
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
Oulipo.n_plus(1, phrase, noun_list).should == 'The badger ate the bat'
|
30
|
+
Oulipo.n_plus(2, phrase, noun_list).should == 'The bat ate the bear'
|
31
|
+
Oulipo.n_plus(6, phrase, noun_list).should == 'The bear ate the badger'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "can be accessed from a string with n_plus" do
|
35
|
+
phrase.n_plus(1, noun_list).should == 'The badger ate the bat'
|
36
|
+
phrase.n_plus(2, noun_list).should == 'The bat ate the bear'
|
37
|
+
phrase.n_plus(6, noun_list).should == 'The bear ate the badger'
|
33
38
|
end
|
34
39
|
|
35
40
|
it "handles unused nouns" do
|
data/spec/univocalisms_spec.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'oulipo/string_em_up'
|
2
3
|
|
3
4
|
describe "univocalisms" do
|
4
5
|
|
5
|
-
let(:performer) { Oulipo }
|
6
|
-
|
7
6
|
let(:univocalism) {
|
8
7
|
<<-POEM
|
9
8
|
No cool monsoons blow soft on Oxford dons,
|
@@ -23,8 +22,11 @@ describe "univocalisms" do
|
|
23
22
|
}
|
24
23
|
|
25
24
|
it "detects a univocalism" do
|
26
|
-
|
27
|
-
|
25
|
+
univocalism.should be_univocalism
|
26
|
+
regular_poem.should_not be_univocalism
|
28
27
|
end
|
29
28
|
|
29
|
+
it "is accessible via Oulipo" do
|
30
|
+
Oulipo.should forward_to_enhanced_string(:univocalism?)
|
31
|
+
end
|
30
32
|
end
|
metadata
CHANGED
@@ -1,28 +1,22 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: oulipo
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
4
5
|
prerelease:
|
5
|
-
version: 0.2.0
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Pete Nicholls
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
date: 2011-07-29 00:00:00 +12:00
|
14
|
-
default_executable:
|
12
|
+
date: 2011-08-01 00:00:00.000000000 Z
|
15
13
|
dependencies: []
|
16
|
-
|
17
14
|
description: Oulipo gives you tools to write constrained stories and poems with Ruby.
|
18
15
|
email: pete@metanation.com
|
19
16
|
executables: []
|
20
|
-
|
21
17
|
extensions: []
|
22
|
-
|
23
18
|
extra_rdoc_files: []
|
24
|
-
|
25
|
-
files:
|
19
|
+
files:
|
26
20
|
- Gemfile
|
27
21
|
- Gemfile.lock
|
28
22
|
- LICENSE
|
@@ -30,6 +24,9 @@ files:
|
|
30
24
|
- Rakefile
|
31
25
|
- lib/oulipo.rb
|
32
26
|
- lib/oulipo/analysis.rb
|
27
|
+
- lib/oulipo/enhanced_string.rb
|
28
|
+
- lib/oulipo/string_em_up.rb
|
29
|
+
- lib/oulipo/string_extensions.rb
|
33
30
|
- lib/oulipo/substitutor.rb
|
34
31
|
- lib/oulipo/word_list.rb
|
35
32
|
- oulipo.gemspec
|
@@ -43,35 +40,31 @@ files:
|
|
43
40
|
- spec/substitution_spec.rb
|
44
41
|
- spec/univocalisms_spec.rb
|
45
42
|
- spec/word_list_spec.rb
|
46
|
-
has_rdoc: true
|
47
43
|
homepage: http://github.com/Aupajo/oulipo
|
48
44
|
licenses: []
|
49
|
-
|
50
45
|
post_install_message:
|
51
46
|
rdoc_options: []
|
52
|
-
|
53
|
-
require_paths:
|
47
|
+
require_paths:
|
54
48
|
- lib
|
55
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
50
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version:
|
61
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
56
|
none: false
|
63
|
-
requirements:
|
64
|
-
- -
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
version:
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
67
61
|
requirements: []
|
68
|
-
|
69
62
|
rubyforge_project:
|
70
|
-
rubygems_version: 1.6
|
63
|
+
rubygems_version: 1.8.6
|
71
64
|
signing_key:
|
72
65
|
specification_version: 3
|
73
66
|
summary: Constrained writing with Ruby.
|
74
|
-
test_files:
|
67
|
+
test_files:
|
75
68
|
- spec/alliteration_spec.rb
|
76
69
|
- spec/analysis_spec.rb
|
77
70
|
- spec/chaterisms_spec.rb
|