oulipo 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.md +76 -0
- data/Rakefile +7 -0
- data/lib/oulipo.rb +49 -0
- data/spec/chaterisms_spec.rb +47 -0
- data/spec/lipograms_spec.rb +24 -0
- data/spec/palindromes_spec.rb +12 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/univocalisms_spec.rb +30 -0
- metadata +64 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Pete Nicholls
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Oulipo
|
2
|
+
|
3
|
+
_String and dance._
|
4
|
+
|
5
|
+
Oulipo gives you tools to write constrained stories and poems with Ruby.
|
6
|
+
|
7
|
+
It's still young, and very much liable to change.
|
8
|
+
|
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
|
+
|
11
|
+
## Lipograms and Pangrams
|
12
|
+
|
13
|
+
Oulipo can detect lipograms and pangrams.
|
14
|
+
|
15
|
+
A lipogram willfully shuns one or more letters of the alphabet.
|
16
|
+
|
17
|
+
In the following snippet of a poem, every letter of the alphabet except 'e' is used:
|
18
|
+
|
19
|
+
stanza = <<-GYLES_BRANDRETH
|
20
|
+
|
21
|
+
Not work of man, nor sport of child
|
22
|
+
Finds Nassan on this mazy wild;
|
23
|
+
Lax grow his joints, limbs toil in vain--
|
24
|
+
Poor wight! why didst thou quit that plain?
|
25
|
+
|
26
|
+
GYLES_BRANDRETH
|
27
|
+
|
28
|
+
Oulipo.lipogram?(stanza) # => true
|
29
|
+
Oulipo.absent_letters(stanza) # => ['e']
|
30
|
+
|
31
|
+
In contrast, a pangram uses all the letters of the alphabet (often seen jumping lazy dogs):
|
32
|
+
|
33
|
+
sentence = 'Big fjords vex quick waltz nymph.'
|
34
|
+
|
35
|
+
Oulipo.pangram?(sentence) # => true
|
36
|
+
|
37
|
+
## Univocalims
|
38
|
+
|
39
|
+
A univocalism is a poem written using only one type of vowel.
|
40
|
+
|
41
|
+
poem = <<-POEM
|
42
|
+
No cool monsoons blow soft on Oxford dons,
|
43
|
+
Orthodox, jog-trot, book-worm Solomons
|
44
|
+
POEM
|
45
|
+
|
46
|
+
Oulipo.univocalism?(poem) # => true
|
47
|
+
|
48
|
+
## Palindromes
|
49
|
+
|
50
|
+
Palindromes read the same way, backwards or forwards:
|
51
|
+
|
52
|
+
Oulipo.palindrome?('Eva, can I stab bats in a cave?') # => true
|
53
|
+
|
54
|
+
## Chaterisms
|
55
|
+
|
56
|
+
Oulipo knows about Chaterisms.
|
57
|
+
|
58
|
+
A chaterism is a poem where either each successive word in the poem grows by one letter (also known as "snowball poem") or shrinks by one letter.
|
59
|
+
|
60
|
+
Oulipo.chaterism? 'Ruby loves poetry!' # => true
|
61
|
+
Oulipo.chaterism? 'Poetry loves Ruby, too.' # => true
|
62
|
+
|
63
|
+
poem = <<-WORDS
|
64
|
+
|
65
|
+
One
|
66
|
+
poem
|
67
|
+
grows,
|
68
|
+
author
|
69
|
+
watches,
|
70
|
+
helpless --
|
71
|
+
syllables
|
72
|
+
accumulate.
|
73
|
+
|
74
|
+
WORDS
|
75
|
+
|
76
|
+
Oulipo.snowball? poem # => true
|
data/Rakefile
ADDED
data/lib/oulipo.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
class Oulipo
|
2
|
+
ALPHABET = 'a'..'z'
|
3
|
+
VOWELS = %w{ a e i o u }
|
4
|
+
|
5
|
+
def self.absent_letters(work)
|
6
|
+
present_letters = work.downcase.split('').uniq
|
7
|
+
missing_letters = ALPHABET.to_a - present_letters
|
8
|
+
missing_letters.empty? ? nil : missing_letters
|
9
|
+
end
|
10
|
+
|
11
|
+
# A pangram uses all letters
|
12
|
+
def self.pangram?(work)
|
13
|
+
self.absent_letters(work).nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
# A lipogram has missing letters
|
17
|
+
def self.lipogram?(work)
|
18
|
+
!self.pangram?(work)
|
19
|
+
end
|
20
|
+
|
21
|
+
# In a chaterism, each successive word is larger than the last or vice versa
|
22
|
+
def self.chaterism?(poem)
|
23
|
+
# Discard the punctuation, split into words
|
24
|
+
words = poem.gsub(/[^a-z\s]/i, '').split
|
25
|
+
|
26
|
+
# Find the direction we're traveling
|
27
|
+
flen, llen = words.first.length, words.last.length
|
28
|
+
direction = flen > llen ? :downto : :upto
|
29
|
+
|
30
|
+
# "The tree sings".map(&:length) # => [3, 4, 5]
|
31
|
+
# [3, 4, 5] == 3.upto(5).to_a # => true
|
32
|
+
words.map(&:length) == flen.send(direction, llen).to_a
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.univocalism?(poem)
|
36
|
+
present_letters = poem.downcase.split('').uniq
|
37
|
+
(VOWELS - present_letters).length == 4
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.snowball?(poem)
|
41
|
+
words = poem.split
|
42
|
+
self.chaterism?(poem) && words.first.length < words.last.length
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.palindrome?(phrase)
|
46
|
+
sequence = phrase.downcase.gsub(/[^a-z]/, '')
|
47
|
+
sequence.reverse == sequence
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "chaterisms" do
|
4
|
+
|
5
|
+
# For easy switching
|
6
|
+
let(:performer) { Oulipo }
|
7
|
+
|
8
|
+
let(:snowball_poem) do
|
9
|
+
<<-POEM
|
10
|
+
The
|
11
|
+
Dark
|
12
|
+
Sings
|
13
|
+
Softly
|
14
|
+
POEM
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:diminishing_poem) do
|
18
|
+
<<-POEM
|
19
|
+
Light's
|
20
|
+
Songs
|
21
|
+
Need
|
22
|
+
Not
|
23
|
+
POEM
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:regular_poem) {
|
27
|
+
<<-POEM
|
28
|
+
Yet if hope has flown away
|
29
|
+
In a night, or in a day,
|
30
|
+
In a vision, or in none,
|
31
|
+
Is it therefore the less gone?
|
32
|
+
POEM
|
33
|
+
}
|
34
|
+
|
35
|
+
it "can detect both diminishing and growing chaterisms" do
|
36
|
+
performer.chaterism?(snowball_poem).should == true
|
37
|
+
performer.chaterism?(diminishing_poem).should == true
|
38
|
+
performer.chaterism?(regular_poem).should == false
|
39
|
+
end
|
40
|
+
|
41
|
+
it "detects a snowball poem" do
|
42
|
+
performer.snowball?(snowball_poem).should == true
|
43
|
+
performer.snowball?(diminishing_poem).should == false
|
44
|
+
performer.snowball?(regular_poem).should == false
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "lipograms and pangrams" do
|
4
|
+
|
5
|
+
# Easy to switch class, if refactored
|
6
|
+
let(:performer) { Oulipo }
|
7
|
+
|
8
|
+
let(:pangram) { 'The quick brown fox jumps over a lazy god' }
|
9
|
+
let(:lipogram) { 'The quick grey fox jumps over lazy gods' }
|
10
|
+
|
11
|
+
it "shows absent letters" do
|
12
|
+
performer.absent_letters(pangram).should == nil
|
13
|
+
performer.absent_letters(lipogram).should == %w{ b n w }
|
14
|
+
end
|
15
|
+
|
16
|
+
it "can tell a pangram from a lipogram" do
|
17
|
+
performer.lipogram?(lipogram).should == true
|
18
|
+
performer.lipogram?(pangram).should == false
|
19
|
+
|
20
|
+
performer.pangram?(pangram).should == true
|
21
|
+
performer.pangram?(lipogram).should == false
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "palindromes" do
|
4
|
+
|
5
|
+
let(:performer) { Oulipo }
|
6
|
+
|
7
|
+
it "detects palindromes" do
|
8
|
+
performer.palindrome?('Mr. Owl ate my metal worm').should == true
|
9
|
+
performer.palindrome?('Carelessness is a dish best served drunk').should == false
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "univocalisms" do
|
4
|
+
|
5
|
+
let(:performer) { Oulipo }
|
6
|
+
|
7
|
+
let(:univocalism) {
|
8
|
+
<<-POEM
|
9
|
+
No cool monsoons blow soft on Oxford dons,
|
10
|
+
Orthodox, jog-trot, book-worm Solomons
|
11
|
+
POEM
|
12
|
+
}
|
13
|
+
|
14
|
+
let (:regular_poem) {
|
15
|
+
<<-POEM
|
16
|
+
And fortune, on his damned quarrel smiling,
|
17
|
+
Showed like a rebel's whore
|
18
|
+
But all's too weak, for brave Macbeth --
|
19
|
+
Well he deserves that name --
|
20
|
+
Disdaining fortune, with his brandished steel,
|
21
|
+
Which smoked with bloody execution
|
22
|
+
POEM
|
23
|
+
}
|
24
|
+
|
25
|
+
it "detects a univocalism" do
|
26
|
+
performer.univocalism?(univocalism).should == true
|
27
|
+
performer.univocalism?(regular_poem).should == false
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oulipo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Pete Nicholls
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-07-28 00:00:00 +12:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: Oulipo gives you tools to write constrained stories and poems with Ruby.
|
18
|
+
email: pete@metanation.com
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files: []
|
24
|
+
|
25
|
+
files:
|
26
|
+
- README.md
|
27
|
+
- Rakefile
|
28
|
+
- LICENSE
|
29
|
+
- lib/oulipo.rb
|
30
|
+
- spec/chaterisms_spec.rb
|
31
|
+
- spec/lipograms_spec.rb
|
32
|
+
- spec/palindromes_spec.rb
|
33
|
+
- spec/spec_helper.rb
|
34
|
+
- spec/univocalisms_spec.rb
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: http://github.com/Aupajo/oulipo
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.6.2
|
60
|
+
signing_key:
|
61
|
+
specification_version: 3
|
62
|
+
summary: Constrained writing with Ruby.
|
63
|
+
test_files: []
|
64
|
+
|