ruby_speech 2.1.2 → 2.2.0

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -2
  3. data/CHANGELOG.md +8 -0
  4. data/README.md +23 -0
  5. data/ext/ruby_speech/extconf.rb +3 -1
  6. data/ext/ruby_speech/ruby_speech.c +4 -1
  7. data/lib/ruby_speech.rb +6 -19
  8. data/lib/ruby_speech/generic_element.rb +141 -29
  9. data/lib/ruby_speech/grxml.rb +16 -22
  10. data/lib/ruby_speech/grxml/element.rb +6 -6
  11. data/lib/ruby_speech/grxml/grammar.rb +29 -12
  12. data/lib/ruby_speech/grxml/item.rb +13 -0
  13. data/lib/ruby_speech/grxml/matcher.rb +5 -1
  14. data/lib/ruby_speech/grxml/one_of.rb +4 -0
  15. data/lib/ruby_speech/grxml/rule.rb +10 -0
  16. data/lib/ruby_speech/grxml/token.rb +3 -0
  17. data/lib/ruby_speech/nlsml.rb +3 -9
  18. data/lib/ruby_speech/ssml.rb +20 -22
  19. data/lib/ruby_speech/ssml/audio.rb +17 -0
  20. data/lib/ruby_speech/ssml/desc.rb +4 -0
  21. data/lib/ruby_speech/ssml/element.rb +5 -3
  22. data/lib/ruby_speech/ssml/emphasis.rb +17 -0
  23. data/lib/ruby_speech/ssml/mark.rb +2 -0
  24. data/lib/ruby_speech/ssml/p.rb +21 -0
  25. data/lib/ruby_speech/ssml/phoneme.rb +2 -0
  26. data/lib/ruby_speech/ssml/prosody.rb +15 -0
  27. data/lib/ruby_speech/ssml/s.rb +20 -0
  28. data/lib/ruby_speech/ssml/say_as.rb +2 -0
  29. data/lib/ruby_speech/ssml/speak.rb +19 -1
  30. data/lib/ruby_speech/ssml/sub.rb +2 -0
  31. data/lib/ruby_speech/ssml/voice.rb +19 -0
  32. data/lib/ruby_speech/version.rb +1 -1
  33. data/ruby_speech.gemspec +2 -3
  34. data/spec/ruby_speech/grxml/grammar_spec.rb +35 -30
  35. data/spec/ruby_speech/grxml/item_spec.rb +8 -6
  36. data/spec/ruby_speech/grxml/one_of_spec.rb +7 -3
  37. data/spec/ruby_speech/grxml/rule_spec.rb +14 -12
  38. data/spec/ruby_speech/grxml/ruleref_spec.rb +5 -3
  39. data/spec/ruby_speech/grxml/tag_spec.rb +6 -2
  40. data/spec/ruby_speech/grxml/token_spec.rb +6 -2
  41. data/spec/ruby_speech/grxml_spec.rb +57 -69
  42. data/spec/ruby_speech/ssml/audio_spec.rb +20 -16
  43. data/spec/ruby_speech/ssml/break_spec.rb +14 -10
  44. data/spec/ruby_speech/ssml/desc_spec.rb +9 -5
  45. data/spec/ruby_speech/ssml/emphasis_spec.rb +17 -13
  46. data/spec/ruby_speech/ssml/mark_spec.rb +7 -3
  47. data/spec/ruby_speech/ssml/p_spec.rb +18 -14
  48. data/spec/ruby_speech/ssml/phoneme_spec.rb +10 -6
  49. data/spec/ruby_speech/ssml/prosody_spec.rb +29 -25
  50. data/spec/ruby_speech/ssml/s_spec.rb +17 -13
  51. data/spec/ruby_speech/ssml/say_as_spec.rb +11 -7
  52. data/spec/ruby_speech/ssml/speak_spec.rb +48 -32
  53. data/spec/ruby_speech/ssml/sub_spec.rb +9 -5
  54. data/spec/ruby_speech/ssml/voice_spec.rb +23 -19
  55. data/spec/ruby_speech/ssml_spec.rb +64 -63
  56. data/spec/spec_helper.rb +0 -3
  57. metadata +10 -31
  58. data/lib/ruby_speech/xml.rb +0 -11
@@ -1,3 +1,14 @@
1
+ require 'ruby_speech/xml/language'
2
+
3
+ %w{
4
+ rule
5
+ item
6
+ one_of
7
+ ruleref
8
+ tag
9
+ token
10
+ }.each { |f| require "ruby_speech/grxml/#{f}" }
11
+
1
12
  module RubySpeech
2
13
  module GRXML
3
14
  ##
@@ -18,7 +29,7 @@ module RubySpeech
18
29
 
19
30
  register :grammar
20
31
 
21
- self.defaults = { :version => '1.0', :language => "en-US" }
32
+ self.defaults = { :version => '1.0', :language => "en-US", namespace: GRXML_NAMESPACE }
22
33
 
23
34
  VALID_CHILD_TYPES = [Nokogiri::XML::Element, Nokogiri::XML::Text, Rule, Tag].freeze
24
35
 
@@ -75,7 +86,8 @@ module RubySpeech
75
86
  # @return [Rule] The root rule node for the document
76
87
  #
77
88
  def root_rule
78
- children(:rule, :id => root).first
89
+ element = rule_with_id root
90
+ self.class.import element if element
79
91
  end
80
92
 
81
93
  ##
@@ -104,12 +116,14 @@ module RubySpeech
104
116
  # @return self
105
117
  #
106
118
  def inline!
107
- xpath("//ns:ruleref", :ns => namespace_href).each do |ref|
108
- rule = children(:rule, :id => ref[:uri].sub(/^#/, '')).first
109
- ref.swap rule.nokogiri_children
119
+ xpath("//ns:ruleref", :ns => GRXML_NAMESPACE).each do |ref|
120
+ rule = rule_with_id ref[:uri].sub(/^#/, '')
121
+ ref.swap rule.children
110
122
  end
111
123
 
112
- non_root_rules = xpath "./ns:rule[@#{namespace_href && Nokogiri.jruby? ? 'ns:' : ''}id!='#{root}']", :ns => namespace_href
124
+ query = "./ns:rule[@id!='#{root}']"
125
+ query += "|./ns:rule[@ns:id!='#{root}']" if Nokogiri.jruby?
126
+ non_root_rules = xpath query, :ns => namespace_href
113
127
  non_root_rules.remove
114
128
 
115
129
  self
@@ -127,10 +141,10 @@ module RubySpeech
127
141
  next if [Token, Tag].include?(element_type)
128
142
 
129
143
  tokens = split_tokens(element).map do |string|
130
- Token.new.tap { |token| token << string }
144
+ Token.new(document).tap { |token| token << string }.node
131
145
  end
132
146
 
133
- element.swap Nokogiri::XML::NodeSet.new(Nokogiri::XML::Document.new, tokens)
147
+ element.swap Nokogiri::XML::NodeSet.new(document, tokens)
134
148
  end
135
149
  end
136
150
 
@@ -143,10 +157,7 @@ module RubySpeech
143
157
  next if element === self
144
158
 
145
159
  imported_element = self.class.import element
146
- next unless imported_element.respond_to? :normalize_whitespace
147
-
148
- imported_element.normalize_whitespace
149
- element.swap imported_element
160
+ imported_element.normalize_whitespace if imported_element.respond_to?(:normalize_whitespace)
150
161
  end
151
162
  end
152
163
 
@@ -178,6 +189,12 @@ module RubySpeech
178
189
  !root || root_rule
179
190
  end
180
191
 
192
+ def rule_with_id(id)
193
+ query = "ns:rule[@id='#{id}']"
194
+ query += "|ns:rule[@ns:id='#{id}']" if Nokogiri.jruby?
195
+ at_xpath query, ns: GRXML_NAMESPACE
196
+ end
197
+
181
198
  def split_tokens(element)
182
199
  element.to_s.split(/(\".*\")/).reject(&:empty?).map do |string|
183
200
  match = string.match /^\"(.*)\"$/
@@ -1,3 +1,5 @@
1
+ require 'ruby_speech/xml/language'
2
+
1
3
  module RubySpeech
2
4
  module GRXML
3
5
  ##
@@ -26,6 +28,17 @@ module RubySpeech
26
28
  # xml:lang declares declaration declares the language of the grammar section for the item element just as xml:lang in the <grammar> element declares for the entire document
27
29
  #
28
30
  class Item < Element
31
+
32
+ %w{
33
+ rule
34
+ one_of
35
+ ruleref
36
+ tag
37
+ token
38
+ }.each { |f| require "ruby_speech/grxml/#{f}" }
39
+
40
+ include XML::Language
41
+
29
42
  Inf = 1.0 / 0.0
30
43
 
31
44
  register :item
@@ -1,3 +1,7 @@
1
+ require 'ruby_speech/grxml/match'
2
+ require 'ruby_speech/grxml/no_match'
3
+ require 'ruby_speech/grxml/potential_match'
4
+ require 'ruby_speech/grxml/max_match'
1
5
  require 'ruby_speech/ruby_speech'
2
6
 
3
7
  if RUBY_PLATFORM =~ /java/
@@ -17,7 +21,7 @@ module RubySpeech
17
21
  def initialize(grammar)
18
22
  @grammar = grammar
19
23
  prepare_grammar
20
- compile_regex regexp_content
24
+ compile_regex regexp_content.gsub(/\?<[\w\d\s]*>/, '')
21
25
  end
22
26
 
23
27
  ##
@@ -1,3 +1,6 @@
1
+ require 'ruby_speech/xml/language'
2
+ require 'ruby_speech/grxml/item'
3
+
1
4
  module RubySpeech
2
5
  module GRXML
3
6
  ##
@@ -13,6 +16,7 @@ module RubySpeech
13
16
  # FIXME: Ensure an 'item' element is in the oneof block... this may be at the final draw or when OneOf is called...
14
17
  #
15
18
  class OneOf < Element
19
+ include XML::Language
16
20
 
17
21
  register :'one-of'
18
22
 
@@ -1,3 +1,13 @@
1
+ require 'ruby_speech/xml/language'
2
+
3
+ %w{
4
+ item
5
+ one_of
6
+ ruleref
7
+ tag
8
+ token
9
+ }.each { |f| require "ruby_speech/grxml/#{f}" }
10
+
1
11
  module RubySpeech
2
12
  module GRXML
3
13
  ##
@@ -1,3 +1,5 @@
1
+ require 'ruby_speech/xml/language'
2
+
1
3
  module RubySpeech
2
4
  module GRXML
3
5
  ##
@@ -9,6 +11,7 @@ module RubySpeech
9
11
  # The token element may include an optional xml:lang attribute to indicate the language of the contained token.
10
12
  #
11
13
  class Token < Element
14
+ include XML::Language
12
15
 
13
16
  register :token
14
17
 
@@ -1,18 +1,12 @@
1
+ require 'ruby_speech/nlsml/document'
2
+ require 'ruby_speech/nlsml/builder'
3
+
1
4
  module RubySpeech
2
5
  module NLSML
3
- extend ActiveSupport::Autoload
4
-
5
6
  NLSML_NAMESPACE = 'http://www.ietf.org/xml/ns/mrcpv2'
6
7
 
7
- eager_autoload do
8
- autoload :Builder
9
- autoload :Document
10
- end
11
-
12
8
  def self.draw(options = {}, &block)
13
9
  Builder.new(options, &block).document
14
10
  end
15
11
  end
16
12
  end
17
-
18
- ActiveSupport::Autoload.eager_autoload!
@@ -1,30 +1,30 @@
1
1
  module RubySpeech
2
2
  module SSML
3
- extend ActiveSupport::Autoload
4
-
5
- eager_autoload do
6
- autoload :Audio
7
- autoload :Break
8
- autoload :Desc
9
- autoload :Element
10
- autoload :Emphasis
11
- autoload :Mark
12
- autoload :P
13
- autoload :Phoneme
14
- autoload :Prosody
15
- autoload :S
16
- autoload :SayAs
17
- autoload :Speak
18
- autoload :Sub
19
- autoload :Voice
20
- end
21
-
22
3
  InvalidChildError = Class.new StandardError
23
4
 
24
5
  SSML_NAMESPACE = 'http://www.w3.org/2001/10/synthesis'
25
6
 
7
+ %w{
8
+ audio
9
+ break
10
+ desc
11
+ element
12
+ emphasis
13
+ mark
14
+ p
15
+ phoneme
16
+ prosody
17
+ s
18
+ say_as
19
+ speak
20
+ sub
21
+ voice
22
+ }.each { |f| require "ruby_speech/ssml/#{f}" }
23
+
26
24
  def self.draw(*args, &block)
27
- Speak.new(*args).tap do |speak|
25
+ document = Nokogiri::XML::Document.new
26
+ Speak.new(document, *args).tap do |speak|
27
+ document.root = speak.node
28
28
  block_return = speak.eval_dsl_block &block
29
29
  speak << block_return if block_return.is_a?(String)
30
30
  end
@@ -35,5 +35,3 @@ module RubySpeech
35
35
  end
36
36
  end # SSML
37
37
  end # RubySpeech
38
-
39
- ActiveSupport::Autoload.eager_autoload!
@@ -1,3 +1,5 @@
1
+ require 'ruby_speech/ssml/element'
2
+
1
3
  module RubySpeech
2
4
  module SSML
3
5
  ##
@@ -14,6 +16,21 @@ module RubySpeech
14
16
  #
15
17
  class Audio < Element
16
18
 
19
+ %w{
20
+ break
21
+ desc
22
+ emphasis
23
+ mark
24
+ p
25
+ phoneme
26
+ prosody
27
+ s
28
+ say_as
29
+ speak
30
+ sub
31
+ voice
32
+ }.each { |f| require "ruby_speech/ssml/#{f}" }
33
+
17
34
  register :audio
18
35
 
19
36
  VALID_CHILD_TYPES = [Nokogiri::XML::Element, Nokogiri::XML::Text, String, Audio, Break, Desc, Emphasis, Mark, P, Phoneme, Prosody, S, SayAs, Sub, Voice].freeze
@@ -1,3 +1,6 @@
1
+ require 'ruby_speech/ssml/element'
2
+ require 'ruby_speech/xml/language'
3
+
1
4
  module RubySpeech
2
5
  module SSML
3
6
  ##
@@ -6,6 +9,7 @@ module RubySpeech
6
9
  # http://www.w3.org/TR/speech-synthesis/#S3.2.2
7
10
  #
8
11
  class Desc < Element
12
+ include XML::Language
9
13
 
10
14
  register :desc
11
15
 
@@ -1,8 +1,8 @@
1
- require 'active_support/core_ext/class/attribute'
1
+ require 'ruby_speech/generic_element'
2
2
 
3
3
  module RubySpeech
4
4
  module SSML
5
- class Element < Niceogiri::XML::Node
5
+ class Element
6
6
  def self.namespace
7
7
  SSML_NAMESPACE
8
8
  end
@@ -17,7 +17,9 @@ module RubySpeech
17
17
 
18
18
  include GenericElement
19
19
 
20
- alias :to_doc :document
20
+ def to_doc
21
+ document
22
+ end
21
23
  end # Element
22
24
  end # SSML
23
25
  end # RubySpeech
@@ -1,3 +1,5 @@
1
+ require 'ruby_speech/ssml/element'
2
+
1
3
  module RubySpeech
2
4
  module SSML
3
5
  ##
@@ -7,6 +9,21 @@ module RubySpeech
7
9
  #
8
10
  class Emphasis < Element
9
11
 
12
+ %w{
13
+ audio
14
+ break
15
+ desc
16
+ mark
17
+ p
18
+ phoneme
19
+ prosody
20
+ s
21
+ say_as
22
+ speak
23
+ sub
24
+ voice
25
+ }.each { |f| require "ruby_speech/ssml/#{f}" }
26
+
10
27
  register :emphasis
11
28
 
12
29
  VALID_LEVELS = [:strong, :moderate, :none, :reduced].freeze
@@ -1,3 +1,5 @@
1
+ require 'ruby_speech/ssml/element'
2
+
1
3
  module RubySpeech
2
4
  module SSML
3
5
  ##
@@ -1,3 +1,6 @@
1
+ require 'ruby_speech/ssml/element'
2
+ require 'ruby_speech/xml/language'
3
+
1
4
  module RubySpeech
2
5
  module SSML
3
6
  ##
@@ -8,6 +11,24 @@ module RubySpeech
8
11
  #
9
12
  class P < Element
10
13
 
14
+ %w{
15
+ audio
16
+ break
17
+ desc
18
+ element
19
+ emphasis
20
+ mark
21
+ phoneme
22
+ prosody
23
+ s
24
+ say_as
25
+ speak
26
+ sub
27
+ voice
28
+ }.each { |f| require "ruby_speech/ssml/#{f}" }
29
+
30
+ include XML::Language
31
+
11
32
  register :p
12
33
 
13
34
  VALID_CHILD_TYPES = [Nokogiri::XML::Element, Nokogiri::XML::Text, String, Audio, Break, Emphasis, Mark, Phoneme, Prosody, S, SayAs, Sub, Voice].freeze
@@ -1,3 +1,5 @@
1
+ require 'ruby_speech/ssml/element'
2
+
1
3
  module RubySpeech
2
4
  module SSML
3
5
  ##
@@ -13,6 +13,21 @@ module RubySpeech
13
13
  #
14
14
  class Prosody < Element
15
15
 
16
+ %w{
17
+ audio
18
+ break
19
+ desc
20
+ emphasis
21
+ mark
22
+ p
23
+ phoneme
24
+ s
25
+ say_as
26
+ speak
27
+ sub
28
+ voice
29
+ }.each { |f| require "ruby_speech/ssml/#{f}" }
30
+
16
31
  register :prosody
17
32
 
18
33
  VALID_PITCHES = [:'x-low', :low, :medium, :high, :'x-high', :default].freeze
@@ -1,3 +1,6 @@
1
+ require 'ruby_speech/ssml/element'
2
+ require 'ruby_speech/xml/language'
3
+
1
4
  module RubySpeech
2
5
  module SSML
3
6
  ##
@@ -8,6 +11,23 @@ module RubySpeech
8
11
  #
9
12
  class S < Element
10
13
 
14
+ %w{
15
+ audio
16
+ break
17
+ desc
18
+ emphasis
19
+ mark
20
+ p
21
+ phoneme
22
+ prosody
23
+ say_as
24
+ speak
25
+ sub
26
+ voice
27
+ }.each { |f| require "ruby_speech/ssml/#{f}" }
28
+
29
+ include XML::Language
30
+
11
31
  register :s
12
32
 
13
33
  VALID_CHILD_TYPES = [Nokogiri::XML::Element, Nokogiri::XML::Text, String, Audio, Break, Emphasis, Mark, Phoneme, Prosody, SayAs, Sub, Voice].freeze