Permalink
Browse files

Merge branch 'release/0.1.2'

  • Loading branch information...
2 parents b0221aa + 2795369 commit 1b83d46e88a2ce342a15ef7006c9666f0e38d79c @benlangfeld committed Jul 7, 2011
View
@@ -1,3 +1,8 @@
+# 0.1.2
+ API Change: SSML.draw now returns a Speak
+ Feature: Speak objects can be turned into an XML document using #to_doc
+ Feature: Speak objects can now be concatenated such that children are merged together
+
# 0.1.1
* Bugfix: DSL now allows for nesting all allowed elements within each other
View
@@ -10,19 +10,30 @@ RubySpeech provides a DSL for constructing SSML documents like so:
```ruby
require 'ruby_speech'
-RubySpeech::SSML.draw do
+speak = RubySpeech::SSML.draw do
voice gender: :male, name: 'fred' do
string "Hi, I'm Fred. The time is currently "
say_as 'date', format: 'dmy' do
"01/02/1960"
end
end
end
+speak.to\_s
```
becomes:
```xml
+<speak xmlns="http://www.w3.org/2001/10/synthesis" version="1.0" xml:lang="en-US">
+ <voice gender="male" name="fred">
+ Hi, I'm Fred. The time is currently <say-as format="dmy" interpret-as="date">01/02/1960</say-as>
+ </voice>
+</speak>
+```
+
+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:
+
+```xml
<?xml version="1.0"?>
<speak xmlns="http://www.w3.org/2001/10/synthesis" version="1.0" xml:lang="en-US">
<voice gender="male" name="fred">
@@ -31,6 +42,8 @@ becomes:
</speak>
```
+You may also then need to call `to_s`.
+
Check out the [YARD documentation](http://rdoc.info/github/benlangfeld/ruby_speech/master/frames) for more
## Features:
@@ -13,12 +13,10 @@ module SSML
InvalidChildError = Class.new StandardError
def self.draw(&block)
- Nokogiri::XML::Document.new.tap do |doc|
- doc << Speak.new.tap do |speak|
- block_return = speak.instance_eval(&block) if block_given?
- speak << block_return if block_return.is_a?(String)
- end
- end.to_s
+ Speak.new.tap do |speak|
+ block_return = speak.instance_eval(&block) if block_given?
+ speak << block_return if block_return.is_a?(String)
+ end
end
end # SSML
end # RubySpeech
@@ -8,7 +8,7 @@ module SSML
class Speak < Element
include XML::Language
- VALID_CHILD_TYPES = [String, Break, Emphasis, Prosody, SayAs, Voice].freeze
+ VALID_CHILD_TYPES = [Nokogiri::XML::Element, String, Break, Emphasis, Prosody, SayAs, Voice].freeze
##
# Create a new SSML speak root element
@@ -45,6 +45,17 @@ def <<(arg)
super
end
+ def to_doc
+ Nokogiri::XML::Document.new.tap do |doc|
+ doc << self
+ end
+ end
+
+ def +(other)
+ other.children.each { |child| self << child }
+ self
+ end
+
def eql?(o)
super o, :language, :base_uri
end
@@ -1,3 +1,3 @@
module RubySpeech
- VERSION = "0.1.1"
+ VERSION = "0.1.2"
end
@@ -118,6 +118,31 @@ module SSML
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")
end
end
+
+ describe "#to_doc" do
+ let(:expected_doc) do
+ Nokogiri::XML::Document.new.tap do |doc|
+ doc << Speak.new
+ end
+ end
+
+ it "should create an XML document from the speak" do
+ Speak.new.to_doc.to_s.should == expected_doc.to_s
+ end
+ end
+
+ it "should allow concatenation" do
+ speak1 = Speak.new
+ speak1 << Voice.new(name: 'frank', content: "Hi, I'm Frank")
+ speak2 = Speak.new
+ speak2 << Voice.new(name: 'millie', content: "Hi, I'm Millie")
+
+ expected_concat = Speak.new
+ expected_concat << Voice.new(name: 'frank', content: "Hi, I'm Frank")
+ expected_concat << Voice.new(name: 'millie', content: "Hi, I'm Millie")
+
+ (speak1 + speak2).to_s.should == expected_concat.to_s
+ end
end # Speak
end # SSML
end # RubySpeech
@@ -3,33 +3,30 @@
module RubySpeech
describe SSML do
describe "#draw" do
- let(:expected_doc) { Nokogiri::XML::Document.new }
-
it "should create an SSML document" do
- expected_doc << SSML::Speak.new
- SSML.draw.should == expected_doc.to_s
+ expected_doc = SSML::Speak.new
+ SSML.draw.to_s.should == expected_doc.to_s
end
describe "when the return value of the block is a string" do
it "should be inserted into the document" do
- expected_doc << SSML::Speak.new(content: "Hi, I'm Fred")
- SSML.draw { "Hi, I'm Fred" }.should == expected_doc.to_s
+ expected_doc = SSML::Speak.new(content: "Hi, I'm Fred")
+ SSML.draw { "Hi, I'm Fred" }.to_s.should == expected_doc.to_s
end
end
describe "when the return value of the block is a string" do
it "should not be inserted into the document" do
- expected_doc << SSML::Speak.new
- SSML.draw { :foo }.should == expected_doc.to_s
+ expected_doc = SSML::Speak.new
+ SSML.draw { :foo }.to_s.should == expected_doc.to_s
end
end
it "should allow other SSML elements to be inserted in the document" do
doc = SSML.draw { voice gender: :male, name: 'fred' }
- speak = SSML::Speak.new
- speak << SSML::Voice.new(gender: :male, name: 'fred')
- expected_doc << speak
- doc.should == expected_doc.to_s
+ expected_doc = SSML::Speak.new
+ expected_doc << SSML::Voice.new(gender: :male, name: 'fred')
+ doc.to_s.should == expected_doc.to_s
end
it "should allow nested block return values" do
@@ -38,10 +35,9 @@ module RubySpeech
"Hi, I'm Fred."
end
end
- speak = SSML::Speak.new
- speak << SSML::Voice.new(gender: :male, name: 'fred', content: "Hi, I'm Fred.")
- expected_doc << speak
- doc.should == expected_doc.to_s
+ expected_doc = SSML::Speak.new
+ expected_doc <<SSML::Voice.new(gender: :male, name: 'fred', content: "Hi, I'm Fred.")
+ doc.to_s.should == expected_doc.to_s
end
it "should allow nested SSML elements" do
@@ -53,12 +49,11 @@ module RubySpeech
end
end
end
- speak = SSML::Speak.new
voice = SSML::Voice.new(gender: :male, name: 'fred', content: "Hi, I'm Fred. The time is currently ")
voice << SSML::SayAs.new('date', format: 'dmy', content: "01/02/1960")
- speak << voice
- expected_doc << speak
- doc.should == expected_doc.to_s
+ expected_doc = SSML::Speak.new
+ expected_doc << voice
+ doc.to_s.should == expected_doc.to_s
end
it "should allow all permutations of possible nested SSML elements" do
@@ -101,32 +96,31 @@ module RubySpeech
end
end
end
- speak = SSML::Speak.new(content: "Hello world.")
- speak << SSML::Break.new
+ expected_doc = SSML::Speak.new(content: "Hello world.")
+ expected_doc << SSML::Break.new
emphasis = SSML::Emphasis.new(content: "HELLO?")
emphasis << SSML::Break.new
emphasis << SSML::Emphasis.new
emphasis << SSML::Prosody.new
emphasis << SSML::SayAs.new('date')
emphasis << SSML::Voice.new
- speak << emphasis
+ expected_doc << emphasis
prosody = SSML::Prosody.new(rate: :slow, content: "H...E...L...L...O?")
prosody << SSML::Break.new
prosody << SSML::Emphasis.new
prosody << SSML::Prosody.new
prosody << SSML::SayAs.new('date')
prosody << SSML::Voice.new
- speak << prosody
- speak << SSML::SayAs.new('date', format: 'dmy', content: "01/02/1960")
+ expected_doc << prosody
+ expected_doc << SSML::SayAs.new('date', format: 'dmy', content: "01/02/1960")
voice = SSML::Voice.new(gender: :male, name: 'fred', content: "Hi, I'm Fred. The time is currently ")
voice << SSML::SayAs.new('date', format: 'dmy', content: "01/02/1960")
voice << SSML::Break.new
voice << SSML::Emphasis.new(content: "I'm so old")
voice << SSML::Prosody.new(rate: :fast, content: "And yet so spritely!")
voice << SSML::Voice.new(age: 12, content: "And I'm young Fred")
- speak << voice
- expected_doc << speak
- doc.should == expected_doc.to_s
+ expected_doc << voice
+ doc.to_s.should == expected_doc.to_s
end
end
end

0 comments on commit 1b83d46

Please sign in to comment.