ruby_speech 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/README.md +14 -1
- data/lib/ruby_speech/ssml/speak.rb +12 -1
- data/lib/ruby_speech/ssml.rb +4 -6
- data/lib/ruby_speech/version.rb +1 -1
- data/spec/ruby_speech/ssml/speak_spec.rb +25 -0
- data/spec/ruby_speech/ssml_spec.rb +22 -28
- metadata +2 -2
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# 0.1.2
|
2
|
+
API Change: SSML.draw now returns a Speak
|
3
|
+
Feature: Speak objects can be turned into an XML document using #to_doc
|
4
|
+
Feature: Speak objects can now be concatenated such that children are merged together
|
5
|
+
|
1
6
|
# 0.1.1
|
2
7
|
* Bugfix: DSL now allows for nesting all allowed elements within each other
|
3
8
|
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ RubySpeech provides a DSL for constructing SSML documents like so:
|
|
10
10
|
```ruby
|
11
11
|
require 'ruby_speech'
|
12
12
|
|
13
|
-
RubySpeech::SSML.draw do
|
13
|
+
speak = RubySpeech::SSML.draw do
|
14
14
|
voice gender: :male, name: 'fred' do
|
15
15
|
string "Hi, I'm Fred. The time is currently "
|
16
16
|
say_as 'date', format: 'dmy' do
|
@@ -18,10 +18,21 @@ RubySpeech::SSML.draw do
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
|
+
speak.to\_s
|
21
22
|
```
|
22
23
|
|
23
24
|
becomes:
|
24
25
|
|
26
|
+
```xml
|
27
|
+
<speak xmlns="http://www.w3.org/2001/10/synthesis" version="1.0" xml:lang="en-US">
|
28
|
+
<voice gender="male" name="fred">
|
29
|
+
Hi, I'm Fred. The time is currently <say-as format="dmy" interpret-as="date">01/02/1960</say-as>
|
30
|
+
</voice>
|
31
|
+
</speak>
|
32
|
+
```
|
33
|
+
|
34
|
+
Once your `Speak` is fully prepared and you're ready to send it off for processing, you must call `to_doc` on it to add the XML header:
|
35
|
+
|
25
36
|
```xml
|
26
37
|
<?xml version="1.0"?>
|
27
38
|
<speak xmlns="http://www.w3.org/2001/10/synthesis" version="1.0" xml:lang="en-US">
|
@@ -31,6 +42,8 @@ becomes:
|
|
31
42
|
</speak>
|
32
43
|
```
|
33
44
|
|
45
|
+
You may also then need to call `to_s`.
|
46
|
+
|
34
47
|
Check out the [YARD documentation](http://rdoc.info/github/benlangfeld/ruby_speech/master/frames) for more
|
35
48
|
|
36
49
|
## Features:
|
@@ -8,7 +8,7 @@ module RubySpeech
|
|
8
8
|
class Speak < Element
|
9
9
|
include XML::Language
|
10
10
|
|
11
|
-
VALID_CHILD_TYPES = [String, Break, Emphasis, Prosody, SayAs, Voice].freeze
|
11
|
+
VALID_CHILD_TYPES = [Nokogiri::XML::Element, String, Break, Emphasis, Prosody, SayAs, Voice].freeze
|
12
12
|
|
13
13
|
##
|
14
14
|
# Create a new SSML speak root element
|
@@ -45,6 +45,17 @@ module RubySpeech
|
|
45
45
|
super
|
46
46
|
end
|
47
47
|
|
48
|
+
def to_doc
|
49
|
+
Nokogiri::XML::Document.new.tap do |doc|
|
50
|
+
doc << self
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def +(other)
|
55
|
+
other.children.each { |child| self << child }
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
48
59
|
def eql?(o)
|
49
60
|
super o, :language, :base_uri
|
50
61
|
end
|
data/lib/ruby_speech/ssml.rb
CHANGED
@@ -13,12 +13,10 @@ module RubySpeech
|
|
13
13
|
InvalidChildError = Class.new StandardError
|
14
14
|
|
15
15
|
def self.draw(&block)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
end.to_s
|
16
|
+
Speak.new.tap do |speak|
|
17
|
+
block_return = speak.instance_eval(&block) if block_given?
|
18
|
+
speak << block_return if block_return.is_a?(String)
|
19
|
+
end
|
22
20
|
end
|
23
21
|
end # SSML
|
24
22
|
end # RubySpeech
|
data/lib/ruby_speech/version.rb
CHANGED
@@ -118,6 +118,31 @@ module RubySpeech
|
|
118
118
|
lambda { subject << 1 }.should raise_error(InvalidChildError, "A Speak can only accept String, Audio, Break, Emphasis, Mark, P, Phoneme, Prosody, SayAs, Sub, S, Voice as children")
|
119
119
|
end
|
120
120
|
end
|
121
|
+
|
122
|
+
describe "#to_doc" do
|
123
|
+
let(:expected_doc) do
|
124
|
+
Nokogiri::XML::Document.new.tap do |doc|
|
125
|
+
doc << Speak.new
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should create an XML document from the speak" do
|
130
|
+
Speak.new.to_doc.to_s.should == expected_doc.to_s
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should allow concatenation" do
|
135
|
+
speak1 = Speak.new
|
136
|
+
speak1 << Voice.new(name: 'frank', content: "Hi, I'm Frank")
|
137
|
+
speak2 = Speak.new
|
138
|
+
speak2 << Voice.new(name: 'millie', content: "Hi, I'm Millie")
|
139
|
+
|
140
|
+
expected_concat = Speak.new
|
141
|
+
expected_concat << Voice.new(name: 'frank', content: "Hi, I'm Frank")
|
142
|
+
expected_concat << Voice.new(name: 'millie', content: "Hi, I'm Millie")
|
143
|
+
|
144
|
+
(speak1 + speak2).to_s.should == expected_concat.to_s
|
145
|
+
end
|
121
146
|
end # Speak
|
122
147
|
end # SSML
|
123
148
|
end # RubySpeech
|
@@ -3,33 +3,30 @@ require 'spec_helper'
|
|
3
3
|
module RubySpeech
|
4
4
|
describe SSML do
|
5
5
|
describe "#draw" do
|
6
|
-
let(:expected_doc) { Nokogiri::XML::Document.new }
|
7
|
-
|
8
6
|
it "should create an SSML document" do
|
9
|
-
expected_doc
|
10
|
-
SSML.draw.should == expected_doc.to_s
|
7
|
+
expected_doc = SSML::Speak.new
|
8
|
+
SSML.draw.to_s.should == expected_doc.to_s
|
11
9
|
end
|
12
10
|
|
13
11
|
describe "when the return value of the block is a string" do
|
14
12
|
it "should be inserted into the document" do
|
15
|
-
expected_doc
|
16
|
-
SSML.draw { "Hi, I'm Fred" }.should == expected_doc.to_s
|
13
|
+
expected_doc = SSML::Speak.new(content: "Hi, I'm Fred")
|
14
|
+
SSML.draw { "Hi, I'm Fred" }.to_s.should == expected_doc.to_s
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
20
18
|
describe "when the return value of the block is a string" do
|
21
19
|
it "should not be inserted into the document" do
|
22
|
-
expected_doc
|
23
|
-
SSML.draw { :foo }.should == expected_doc.to_s
|
20
|
+
expected_doc = SSML::Speak.new
|
21
|
+
SSML.draw { :foo }.to_s.should == expected_doc.to_s
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
25
|
it "should allow other SSML elements to be inserted in the document" do
|
28
26
|
doc = SSML.draw { voice gender: :male, name: 'fred' }
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
doc.should == expected_doc.to_s
|
27
|
+
expected_doc = SSML::Speak.new
|
28
|
+
expected_doc << SSML::Voice.new(gender: :male, name: 'fred')
|
29
|
+
doc.to_s.should == expected_doc.to_s
|
33
30
|
end
|
34
31
|
|
35
32
|
it "should allow nested block return values" do
|
@@ -38,10 +35,9 @@ module RubySpeech
|
|
38
35
|
"Hi, I'm Fred."
|
39
36
|
end
|
40
37
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
doc.should == expected_doc.to_s
|
38
|
+
expected_doc = SSML::Speak.new
|
39
|
+
expected_doc <<SSML::Voice.new(gender: :male, name: 'fred', content: "Hi, I'm Fred.")
|
40
|
+
doc.to_s.should == expected_doc.to_s
|
45
41
|
end
|
46
42
|
|
47
43
|
it "should allow nested SSML elements" do
|
@@ -53,12 +49,11 @@ module RubySpeech
|
|
53
49
|
end
|
54
50
|
end
|
55
51
|
end
|
56
|
-
speak = SSML::Speak.new
|
57
52
|
voice = SSML::Voice.new(gender: :male, name: 'fred', content: "Hi, I'm Fred. The time is currently ")
|
58
53
|
voice << SSML::SayAs.new('date', format: 'dmy', content: "01/02/1960")
|
59
|
-
|
60
|
-
expected_doc <<
|
61
|
-
doc.should == expected_doc.to_s
|
54
|
+
expected_doc = SSML::Speak.new
|
55
|
+
expected_doc << voice
|
56
|
+
doc.to_s.should == expected_doc.to_s
|
62
57
|
end
|
63
58
|
|
64
59
|
it "should allow all permutations of possible nested SSML elements" do
|
@@ -101,32 +96,31 @@ module RubySpeech
|
|
101
96
|
end
|
102
97
|
end
|
103
98
|
end
|
104
|
-
|
105
|
-
|
99
|
+
expected_doc = SSML::Speak.new(content: "Hello world.")
|
100
|
+
expected_doc << SSML::Break.new
|
106
101
|
emphasis = SSML::Emphasis.new(content: "HELLO?")
|
107
102
|
emphasis << SSML::Break.new
|
108
103
|
emphasis << SSML::Emphasis.new
|
109
104
|
emphasis << SSML::Prosody.new
|
110
105
|
emphasis << SSML::SayAs.new('date')
|
111
106
|
emphasis << SSML::Voice.new
|
112
|
-
|
107
|
+
expected_doc << emphasis
|
113
108
|
prosody = SSML::Prosody.new(rate: :slow, content: "H...E...L...L...O?")
|
114
109
|
prosody << SSML::Break.new
|
115
110
|
prosody << SSML::Emphasis.new
|
116
111
|
prosody << SSML::Prosody.new
|
117
112
|
prosody << SSML::SayAs.new('date')
|
118
113
|
prosody << SSML::Voice.new
|
119
|
-
|
120
|
-
|
114
|
+
expected_doc << prosody
|
115
|
+
expected_doc << SSML::SayAs.new('date', format: 'dmy', content: "01/02/1960")
|
121
116
|
voice = SSML::Voice.new(gender: :male, name: 'fred', content: "Hi, I'm Fred. The time is currently ")
|
122
117
|
voice << SSML::SayAs.new('date', format: 'dmy', content: "01/02/1960")
|
123
118
|
voice << SSML::Break.new
|
124
119
|
voice << SSML::Emphasis.new(content: "I'm so old")
|
125
120
|
voice << SSML::Prosody.new(rate: :fast, content: "And yet so spritely!")
|
126
121
|
voice << SSML::Voice.new(age: 12, content: "And I'm young Fred")
|
127
|
-
|
128
|
-
|
129
|
-
doc.should == expected_doc.to_s
|
122
|
+
expected_doc << voice
|
123
|
+
doc.to_s.should == expected_doc.to_s
|
130
124
|
end
|
131
125
|
end
|
132
126
|
end
|