phonology 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Norman Clarke
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # Phonology
2
+
3
+ Some phonology utilities for Ruby. In progress, so no documentation yet.
4
+
5
+ To see some of the things you can do, take a peek at the tests.
@@ -0,0 +1,182 @@
1
+ module Phonology
2
+
3
+ # Raised for any attempt to access an invalid feature.
4
+ class FeatureError < StandardError; end
5
+
6
+ # Distinctive features.
7
+ module Features
8
+
9
+ # Pulmonic consonants
10
+ PULMONIC = [:nasal, :plosive, :fricative, :approximant, :trill, :flap,
11
+ :lateral, :bilabial, :labiodental, :dental, :alveolar, :postalveolar,
12
+ :retroflex, :palatal, :velar, :uvular, :pharyngeal, :epiglottal, :glottal]
13
+
14
+ # Non-pulmonic consonants
15
+ NON_PULMONIC = [:click, :implosive, :ejective]
16
+
17
+ # Vocalic features
18
+ VOCALIC = [:close, :near_close, :close_mid, :mid, :open_mid, :near_open, :open,
19
+ :front, :near_front, :central, :near_back, :back, :rounded]
20
+
21
+ # Consontal features
22
+ CONSONANTAL = (PULMONIC + NON_PULMONIC).to_set
23
+
24
+ # All features classes
25
+ ALL = ([:voiced] + PULMONIC + NON_PULMONIC + VOCALIC).to_set
26
+
27
+ # Manner of articulation features
28
+ MANNER = [:nasal, :plosive, :fricative, :approximant, :trill, :flap, :lateral] + NON_PULMONIC
29
+
30
+ # Place of articulation features
31
+ PLACE = CONSONANTAL.to_a - MANNER
32
+
33
+ # Vowel height
34
+ HEIGHT = [:close, :near_close, :close_mid, :mid, :open_mid, :near_open, :open]
35
+
36
+ # Vowel backness
37
+ BACKNESS = (VOCALIC.to_set - HEIGHT - [:rounded])
38
+
39
+ # Feature classes
40
+ CLASSES = {
41
+ :labial => [:bilabial, :labiodental].to_set,
42
+ :coronal => [:dental, :alveolar, :postalveolar, :retroflex].to_set,
43
+ :dorsal => [:palatal, :velar, :uvular].to_set,
44
+ :radical => [:pharyngeal, :epiglottal].to_set,
45
+ :vocalic => VOCALIC + [:rounded],
46
+ :non_pulmonic => NON_PULMONIC,
47
+ :pulmonic => PULMONIC,
48
+ :consonantal => CONSONANTAL
49
+ }
50
+
51
+ # Sets of distinctive features mapped to an IPA symbol
52
+ SETS = {
53
+ [:voiced, :bilabial, :nasal].to_set => [0x006d],
54
+ [:voiced, :labiodental, :nasal].to_set => [0x0271],
55
+ [:voiced, :alveolar, :nasal].to_set => [0x006e],
56
+ [:voiced, :retroflex, :nasal].to_set => [0x0273],
57
+ [:voiced, :palatal, :nasal].to_set => [0x0272],
58
+ [:voiced, :velar, :nasal].to_set => [0x014b],
59
+ [:voiced, :uvular, :nasal].to_set => [0x0274],
60
+ [:bilabial, :plosive].to_set => [0x0070],
61
+ [:voiced, :bilabial, :plosive].to_set => [0x0062],
62
+ [:labiodental, :plosive].to_set => [0x0070, 0x032a],
63
+ [:voiced, :labiodental, :plosive].to_set => [0x0062, 0x032a],
64
+ [:alveolar, :plosive].to_set => [0x0074],
65
+ [:voiced, :alveolar, :plosive].to_set => [0x0064],
66
+ [:retroflex, :plosive].to_set => [0x0288],
67
+ [:voiced, :retroflex, :plosive].to_set => [0x0256],
68
+ [:palatal, :plosive].to_set => [0x0063],
69
+ [:voiced, :palatal, :plosive].to_set => [0x025f],
70
+ [:velar, :plosive].to_set => [0x006b],
71
+ [:voiced, :velar, :plosive].to_set => [0x0261],
72
+ [:uvular, :plosive].to_set => [0x0071],
73
+ [:voiced, :uvular, :plosive].to_set => [0x0262],
74
+ [:voiced, :epiglottal, :plosive].to_set => [0x02a1],
75
+ [:voiced, :glottal, :plosive].to_set => [0x0294],
76
+ [:bilabial, :fricative].to_set => [0x0278],
77
+ [:voiced, :bilabial, :fricative].to_set => [0x03b2],
78
+ [:labiodental, :fricative].to_set => [0x0066],
79
+ [:voiced, :labiodental, :fricative].to_set => [0x0076],
80
+ [:dental, :fricative].to_set => [0x03b8],
81
+ [:voiced, :dental, :fricative].to_set => [0x00f0],
82
+ [:alveolar, :fricative].to_set => [0x0073],
83
+ [:voiced, :alveolar, :fricative].to_set => [0x007a],
84
+ [:postalveolar, :fricative].to_set => [0x0283],
85
+ [:voiced, :postalveolar, :fricative].to_set => [0x0292],
86
+ [:retroflex, :fricative].to_set => [0x0282],
87
+ [:voiced, :retroflex, :fricative].to_set => [0x0290],
88
+ [:palatal, :fricative].to_set => [0x00e7],
89
+ [:voiced, :palatal, :fricative].to_set => [0x029d],
90
+ [:velar, :fricative].to_set => [0x0078],
91
+ [:voiced, :velar, :fricative].to_set => [0x0263],
92
+ [:uvular, :fricative].to_set => [0x03c7],
93
+ [:voiced, :uvular, :fricative, :approximant].to_set => [0x0281],
94
+ [:pharyngeal, :fricative].to_set => [0x0127],
95
+ [:voiced, :pharyngeal, :fricative, :approximant].to_set => [0x0295],
96
+ [:epiglottal, :fricative].to_set => [0x029c],
97
+ [:voiced, :epiglottal, :fricative, :approximant].to_set => [0x02a2],
98
+ [:glottal, :fricative, :approximant].to_set => [0x0068],
99
+ [:voiced, :glottal, :fricative, :approximant].to_set => [0x0266],
100
+ [:voiced, :bilabial, :approximant].to_set => [0x03b2, 0x031e],
101
+ [:voiced, :labiodental, :approximant].to_set => [0x028b],
102
+ [:voiced, :alveolar, :approximant].to_set => [0x0279],
103
+ [:voiced, :retroflex, :approximant].to_set => [0x027b],
104
+ [:voiced, :palatal, :approximant].to_set => [0x006a],
105
+ [:voiced, :velar, :approximant].to_set => [0x0270],
106
+ [:voiced, :bilabial, :trill].to_set => [0x0299],
107
+ [:voiced, :alveolar, :trill].to_set => [0x0072],
108
+ [:voiced, :uvular, :trill].to_set => [0x0280],
109
+ [:voiced, :epiglottal, :trill].to_set => [0x044f],
110
+ [:voiced, :bilabial, :flap].to_set => [0x2c71, 0x031f],
111
+ [:voiced, :labiodental, :flap].to_set => [0x2c71],
112
+ [:voiced, :alveolar, :flap].to_set => [0x027e],
113
+ [:voiced, :retroflex, :flap].to_set => [0x027d],
114
+ [:voiced, :uvular, :flap].to_set => [0x0262, 0x0306],
115
+ [:voiced, :epiglottal, :flap].to_set => [0x02a1, 0x032f],
116
+ [:alveolar, :lateral, :fricative].to_set => [0x026c],
117
+ [:voiced, :alveolar, :lateral, :fricative].to_set => [0x026e],
118
+ [:voiced, :alveolar, :lateral, :approximant].to_set => [0x006c],
119
+ [:voiced, :retroflex, :lateral, :approximant].to_set => [0x026d],
120
+ [:voiced, :palatal, :lateral, :approximant].to_set => [0x028e],
121
+ [:voiced, :velar, :lateral, :approximant].to_set => [0x029f],
122
+ [:voiced, :alveolar, :lateral, :flap].to_set => [0x027a],
123
+ [:voiced, :palatal, :lateral, :flap].to_set => [0x028e, 0x032f],
124
+ [:voiced, :velar, :lateral, :flap].to_set => [0x029f, 0x0306],
125
+ [:voiced, :close, :front].to_set => [0x0069],
126
+ [:voiced, :close, :front, :rounded].to_set => [0x0079],
127
+ [:voiced, :close, :central].to_set => [0x0268],
128
+ [:voiced, :close, :central, :rounded].to_set => [0x0289],
129
+ [:voiced, :close, :back].to_set => [0x026f],
130
+ [:voiced, :close, :back, :rounded].to_set => [0x0075],
131
+ [:voiced, :near_close, :near_front].to_set => [0x026a],
132
+ [:voiced, :near_close, :near_front, :rounded].to_set => [0x028f],
133
+ [:voiced, :near_close, :near_back, :rounded].to_set => [0x028a],
134
+ [:voiced, :close_mid, :front].to_set => [0x0065],
135
+ [:voiced, :close_mid, :front, :rounded].to_set => [0x00f8],
136
+ [:voiced, :close_mid, :central].to_set => [0x0258],
137
+ [:voiced, :close_mid, :central, :rounded].to_set => [0x0275],
138
+ [:voiced, :close_mid, :back].to_set => [0x0264],
139
+ [:voiced, :close_mid, :back, :rounded].to_set => [0x006f],
140
+ [:voiced, :mid, :central].to_set => [0x0259],
141
+ [:voiced, :open_mid, :front].to_set => [0x025b],
142
+ [:voiced, :open_mid, :front, :rounded].to_set => [0x0153],
143
+ [:voiced, :open_mid, :central].to_set => [0x025c],
144
+ [:voiced, :open_mid, :central, :rounded].to_set => [0x025e],
145
+ [:voiced, :open_mid, :back].to_set => [0x028c],
146
+ [:voiced, :open_mid, :back, :rounded].to_set => [0x0254],
147
+ [:voiced, :near_open, :front].to_set => [0x00e6],
148
+ [:voiced, :near_open, :central].to_set => [0x0250],
149
+ [:voiced, :open, :front].to_set => [0x0061],
150
+ [:voiced, :open, :front, :rounded].to_set => [0x0276],
151
+ [:voiced, :open, :back].to_set => [0x0251],
152
+ [:voiced, :open, :back, :rounded].to_set => [0x0252],
153
+ # This char will appear in Unicode 6.0
154
+ [:voiced, :retroflex, :lateral, :fricative].to_set => [0xa78e],
155
+ # Not in UTF-8; used in SIL International's Charis/Doulos font's private
156
+ # use area
157
+ [:voiced, :palatal, :lateral, :fricative].to_set => [0xf267],
158
+ [:voiced, :velar, :lateral, :fricative].to_set => [0xf268],
159
+ [:voiced, :retroflex, :lateral, :flap].to_set => [0xf269]
160
+ }
161
+
162
+ class << self
163
+ # Return the set corresponding to the kind of feature: manner or place of
164
+ # articulation, or height or backness.
165
+ def set(feature)
166
+ [MANNER, PLACE, BACKNESS, HEIGHT].each {|kind| return kind if kind.include? feature}
167
+ nil
168
+ end
169
+
170
+ # Given a Ruby :symbol feature class such as :coronal, return the
171
+ # corresponding features. If a single feature is given, just return the
172
+ # feature.
173
+ def expand(*args)
174
+ args = args.inject([].to_set) do |memo, obj|
175
+ memo << (CLASSES[obj] || obj)
176
+ end.flatten.to_set
177
+ end
178
+
179
+ end
180
+
181
+ end
182
+ end
@@ -0,0 +1,103 @@
1
+ module Phonology
2
+
3
+ # A set of distinctive features
4
+ class Sound
5
+
6
+ attr_reader :features
7
+
8
+ def initialize(*features)
9
+ @features = if features.first.kind_of?(String)
10
+ Phonology.features(features.shift)
11
+ else
12
+ features.to_set
13
+ end
14
+ end
15
+
16
+ Features::ALL.each do |feature|
17
+ class_eval(<<-EOM, __FILE__, __LINE__ +1)
18
+ def #{feature}?
19
+ @features.include? :#{feature}
20
+ end
21
+ EOM
22
+ end
23
+
24
+ Features::CLASSES.each do |feature_class, values|
25
+ class_eval(<<-EOM, __FILE__, __LINE__ +1)
26
+ def #{feature_class}?
27
+ set = Features.expand(:#{feature_class})
28
+ !set.intersection(@features).empty?
29
+ end
30
+ EOM
31
+ end
32
+
33
+ # Get the IPA symbol for the sound.
34
+ def symbol
35
+ Phonology.symbol(features)
36
+ end
37
+
38
+ # Add a feature, replacing either the place or manner of articulation,
39
+ # or the height or backness. Returns self.
40
+ def <<(feature)
41
+ feature = feature.to_sym
42
+ (@features -= (Features.set(feature) || [])) << feature
43
+ self
44
+ end
45
+ alias add <<
46
+
47
+ # Remove a feature, and return self.
48
+ def >>(feature)
49
+ @features -= [feature.to_sym]
50
+ self
51
+ end
52
+
53
+ # Get the next sound, moving backwards in the mouth.
54
+ def backward
55
+ if consonantal?
56
+ index = Features::PLACE.index(place.first)
57
+ max = Features::PLACE.length
58
+ features = @features - Features::PLACE
59
+ until index > max do
60
+ index = index + 1
61
+ feature = Features::PLACE[index]
62
+ if self.class.exists?(features + [feature])
63
+ @features = features + [feature]
64
+ return self
65
+ end
66
+ end
67
+ end
68
+ self
69
+ end
70
+
71
+ def forward
72
+ end
73
+
74
+ # Get the sound's place of articulation.
75
+ def place
76
+ @features.intersection(Features::PLACE)
77
+ end
78
+
79
+ # Get the sound's manner of articulation.
80
+ def manner
81
+ @features.intersection(Features::MANNER)
82
+ end
83
+
84
+ # Get the sound's height.
85
+ def height
86
+ @features.intersection(Features::HEIGHT)
87
+ end
88
+
89
+ # Get the sound's backness.
90
+ def backness
91
+ @features.intersection(Features::BACKNESS)
92
+ end
93
+
94
+ def exists?
95
+ self.class.exists?(@features)
96
+ end
97
+
98
+ def self.exists?(features)
99
+ !! Features::SETS[features]
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,69 @@
1
+ module Phonology
2
+
3
+ # An inventory of Phonological feature sets.
4
+ class Sounds
5
+
6
+ # A Hash with a set of features as keys, and UTF-8 codepoints for IPA
7
+ # letters as values.
8
+ attr :sets
9
+
10
+ # Get an instance, building its set from a list IPA characters.
11
+ def self.from_ipa(*chars)
12
+ chars = chars.flatten.map {|char| char.unpack("U*")}
13
+ new Features::SETS.select {|key, val| chars.include? val}
14
+ end
15
+
16
+ def initialize(sets)
17
+ @sets = sets
18
+ end
19
+
20
+ # Given an IPA symbol, return a corresponding set of distinctive features.
21
+ def features(symbol)
22
+ @sets.key(symbol.unpack("U*"))
23
+ end
24
+
25
+ # Given a set of features, return an IPA symbol
26
+ def symbol(*features)
27
+ codepoints(features).pack("U*")
28
+ end
29
+
30
+ def symbols
31
+ @sets.values.map {|symbol| symbol.pack("U*")}.to_set
32
+ end
33
+
34
+ # Given a set of features, return an array of UTF-8 codepoints.
35
+ def codepoints(features)
36
+ features = features.to_set.flatten
37
+ @sets[features] || (raise FeatureError, "No such set #{features.inspect}")
38
+ end
39
+
40
+ # Return an instance of Sounds whose sets include any of the given
41
+ # features.
42
+ def with(*features)
43
+ features = features.to_set
44
+ self.class.new @sets.select {|key, val| !key.intersection(features).empty?}
45
+ end
46
+
47
+ # Return feature sets that include all of the given features
48
+ def with_all(*features)
49
+ features = features.to_set
50
+ self.class.new @sets.select {|key, val| features.subset?(key)}
51
+ end
52
+
53
+ # Return an instance of Sounds whose sets exclude any of the given
54
+ # features.
55
+ def without(*features)
56
+ features = features.to_set
57
+ self.class.new @sets.select {|key, val| !features.subset?(key)}
58
+ end
59
+
60
+ # Return an instance of Sounds whose sets exclude all of the given
61
+ # features.
62
+ def without_any(*features)
63
+ features = features.to_set
64
+ self.class.new @sets.select {|key, val| key.intersection(features).empty?}
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,3 @@
1
+ module Phonology
2
+ VERSION = "0.0.1"
3
+ end
data/lib/phonology.rb ADDED
@@ -0,0 +1,22 @@
1
+ require "set"
2
+ require File.expand_path("../phonology/features", __FILE__)
3
+ require File.expand_path("../phonology/sounds", __FILE__)
4
+ require File.expand_path("../phonology/sound", __FILE__)
5
+
6
+ module Phonology
7
+
8
+ extend self
9
+
10
+ def sounds
11
+ @sounds ||= Sounds.new Features::SETS
12
+ end
13
+
14
+ def symbol(*args)
15
+ sounds.symbol(*args)
16
+ end
17
+
18
+ def features(*args)
19
+ sounds.features(*args)
20
+ end
21
+
22
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path("../test_helper", __FILE__)
2
+
3
+ class FeaturesTest < Test::Unit::TestCase
4
+
5
+ test "should expand feature groups" do
6
+ assert_equal [:dental, :alveolar, :postalveolar, :retroflex, :velar].to_set,
7
+ Phonology::Features.expand(:coronal, :dental, :velar)
8
+ end
9
+
10
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path("../test_helper", __FILE__)
2
+
3
+ class PhonologyTest < Test::Unit::TestCase
4
+
5
+ test "sounds should return an instance of Sounds" do
6
+ assert_equal Phonology::Sounds, Phonology.sounds.class
7
+ end
8
+
9
+ test "should return feature set for symbol" do
10
+ assert_equal [:voiced, :bilabial, :nasal].to_set, Phonology.features("m")
11
+ end
12
+
13
+ test "should return a symbol for a feature set" do
14
+ assert_equal "d", Phonology.symbol(:voiced, :alveolar, :plosive)
15
+ end
16
+
17
+ end
@@ -0,0 +1,84 @@
1
+ require File.expand_path("../test_helper", __FILE__)
2
+
3
+ class SoundTest < Test::Unit::TestCase
4
+
5
+ include Phonology
6
+
7
+ test "should return an IPA symbol" do
8
+ assert_equal "m", Sound.new(:voiced, :bilabial, :nasal).symbol
9
+ end
10
+
11
+ test "should instantiate from IPA symbol" do
12
+ assert_equal [:voiced, :bilabial, :nasal].to_set, Sound.new("m").features
13
+ end
14
+
15
+ test "should indicate individual features" do
16
+ assert Sound.new("n").nasal?
17
+ end
18
+
19
+ test "should indicate feature classes" do
20
+ assert Sound.new("n").coronal?
21
+ assert Sound.new("n").consonantal?
22
+ assert !Sound.new("n").vocalic?
23
+ end
24
+
25
+ test "should add/remove voice" do
26
+ sound = Sound.new("p")
27
+ sound << :voiced
28
+ assert_equal "b", sound.symbol
29
+ sound >> :voiced
30
+ assert_equal "p", sound.symbol
31
+ end
32
+
33
+ test "should add/remove rounding" do
34
+ sound = Sound.new("a")
35
+ sound << :rounded
36
+ assert_equal "\u0276", sound.symbol
37
+ sound >> :rounded
38
+ assert_equal "a", sound.symbol
39
+ end
40
+
41
+ test "should change manner of articulation" do
42
+ sound = Sound.new("m")
43
+ sound << :plosive
44
+ assert_equal "b", sound.symbol
45
+ end
46
+
47
+ test "should change place of articulation" do
48
+ assert_equal "n", Sound.new("m").add(:alveolar).symbol
49
+ end
50
+
51
+ test "should change backness" do
52
+ assert_equal "u", Sound.new("y").add(:back).symbol
53
+ end
54
+
55
+ test "should change height" do
56
+ assert_equal "i", Sound.new("a").add(:close).symbol
57
+ end
58
+
59
+ test "should get place of articulation" do
60
+ assert_equal :alveolar, Sound.new("r").place.first
61
+ end
62
+
63
+ test "should get manner of articulation" do
64
+ assert_equal :trill, Sound.new("r").manner.first
65
+ end
66
+
67
+ test "should get height" do
68
+ assert_equal :close_mid, Sound.new("e").height.first
69
+ end
70
+
71
+ test "should get backness" do
72
+ assert_equal :front, Sound.new("e").backness.first
73
+ end
74
+
75
+ test "should indicate if sound exists" do
76
+ assert !Sound.new(:front, :plosive).exists?
77
+ assert Sound.new(:bilabial, :plosive).exists?
78
+ end
79
+
80
+ test "should move sounds backwards" do
81
+ assert_equal "n", Sound.new("m").backward.backward.symbol
82
+ end
83
+
84
+ end
@@ -0,0 +1,32 @@
1
+ require File.expand_path("../test_helper", __FILE__)
2
+
3
+ class SoundsTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @sounds = Phonology.sounds
7
+ end
8
+
9
+ def small_set
10
+ Phonology::Sounds.from_ipa("b", "p", "d", "t", "m", "n")
11
+ end
12
+
13
+ test "should return feature set for symbol" do
14
+ assert_equal [:voiced, :bilabial, :nasal].to_set, @sounds.features("m")
15
+ end
16
+
17
+ test "#with should return a set of sets that include any of the given features" do
18
+ assert_equal ["p", "b", "m", "n"].to_set, small_set.with(:bilabial, :nasal).symbols
19
+ end
20
+
21
+ test "#without should return a set of sets that exclude any of the given features" do
22
+ assert_equal ["p", "b", "n", "d", "t"].to_set, small_set.without(:bilabial, :nasal).symbols
23
+ end
24
+
25
+ test "#with_all should return a set of sets that include any of the given features" do
26
+ assert_equal ["m"].to_set, small_set.with_all(:bilabial, :nasal).symbols
27
+ end
28
+
29
+ test "#without_any should return a set of sets that exclude all of the given features" do
30
+ assert_equal ["d", "t"].to_set, small_set.without_any(:bilabial, :nasal).symbols
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ require "test/unit"
2
+ require File.expand_path("../../lib/phonology", __FILE__)
3
+
4
+ Test::Unit::TestCase.extend Module.new {
5
+ def test(name, &block)
6
+ define_method("test_#{name.gsub(/[^a-z0-9]/i, "_")}".to_sym, &block)
7
+ end
8
+ alias should test
9
+ }
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: phonology
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Norman Clarke
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-06 00:00:00 -03:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: A phonology library for Ruby.
22
+ email: norman@njclarke.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - lib/phonology.rb
31
+ - lib/phonology/features.rb
32
+ - lib/phonology/sound.rb
33
+ - lib/phonology/sounds.rb
34
+ - lib/phonology/version.rb
35
+ - test/features_test.rb
36
+ - test/phonology_test.rb
37
+ - test/sound_test.rb
38
+ - test/sounds_test.rb
39
+ - test/test_helper.rb
40
+ - README.md
41
+ - LICENSE
42
+ has_rdoc: true
43
+ homepage: http://github.com/norman/phonology
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ requirements: []
66
+
67
+ rubyforge_project: "[none]"
68
+ rubygems_version: 1.3.6
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Phonology library for Ruby
72
+ test_files: []
73
+