ruby_speech 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|