ruby_speech 2.1.2 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: caf6dc66fd5b216e0825c25c2df9c16324e955e1
4
- data.tar.gz: ecd61a61b6a362521b6915d7eac46b47556f55c0
3
+ metadata.gz: ec0d77b52aa0d3a5f6984d3a966592337bf744b8
4
+ data.tar.gz: dd2535eab8d121f262017bd29cb881021652b1ea
5
5
  SHA512:
6
- metadata.gz: 1a08ac02e15a99aaf0f4ec753cb22fbf63304d4d42df34215dffe15255d344cf2d06bc23ab448f2152069e1c074d3d47b9a4978a4e04a1a746124a5658ce8a1e
7
- data.tar.gz: 4a96f1f2fb4a56a08f6328bd6caa89ec4b47ee8638ee1c0d2e7bd3e2a867274b1d19d43039b423144e7e195140380e474c1533109e5ca0d165fc919e3b63fc69
6
+ metadata.gz: 23a82e611e67b400e6fd06560e5ae7bcec8a68df565ac6c82378dcb2d86378ac75696b5f6399f39d275c8c98ec9cc0126209b60f1b78bf262bc2b97b65f7f453
7
+ data.tar.gz: 9816cb0183ec5138a976417b27beae562590eba32d205076294855a8160f763828bfc84a548fa603e5758970cc73affe65838e84dc541c4abf3054b5bd71ee2c
data/.travis.yml CHANGED
@@ -1,7 +1,6 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 1.9.2
5
4
  - 1.9.3
6
5
  - 2.0.0
7
6
  - jruby-19mode
@@ -9,7 +8,7 @@ rvm:
9
8
  - ruby-head
10
9
  matrix:
11
10
  allow_failures:
12
- # - rvm: jruby-19mode
11
+ - rvm: ruby-head
13
12
  before_install:
14
13
  - sudo apt-get install libpcre3 libpcre3-dev
15
14
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # [develop](https://github.com/benlangfeld/ruby_speech)
2
2
 
3
+ # [2.2.0](https://github.com/benlangfeld/ruby_speech/compare/v2.1.2...v2.2.0) - [2013-06-26](https://rubygems.org/gems/ruby_speech/versions/2.2.0)
4
+ * Bugfix: Constant autoload in rbx C extensions doesn't work properly
5
+ * Bugfix: No longer subclass or copy nodes, use delegation instead
6
+ * Bugfix: Java 1.6 compatability
7
+ * CS: Remove niceogiri dependency
8
+ * CS: Remove autoloading
9
+ * CS: Depend on activesupport less
10
+
3
11
  # [2.1.2](https://github.com/benlangfeld/ruby_speech/compare/v2.1.1...v2.1.2) - [2013-06-05](https://rubygems.org/gems/ruby_speech/versions/2.1.2)
4
12
  * Bugfix: Allow wrapping a pre-parsed XML node nested arbitrary deeply as an NLSML document
5
13
 
data/README.md CHANGED
@@ -1,9 +1,32 @@
1
1
  # RubySpeech
2
2
  RubySpeech is a library for constructing and parsing Text to Speech (TTS) and Automatic Speech Recognition (ASR) documents such as [SSML](http://www.w3.org/TR/speech-synthesis), [GRXML](http://www.w3.org/TR/speech-grammar/) and [NLSML](http://www.w3.org/TR/nl-spec/). Such documents can be constructed to be processed by TTS and ASR engines, parsed as the result from such, or used in the implementation of such engines.
3
3
 
4
+ ## Dependencies
5
+
6
+ ### pcre (except on JRuby)
7
+
8
+ #### On OSX with Homebrew
9
+ ```
10
+ brew install pcre
11
+ ```
12
+
13
+ #### On Ubuntu/Debian
14
+ ```
15
+ sudo apt-get install libpcre3 libpcre3-dev
16
+ ```
17
+
18
+ #### On CentOS
19
+ ```
20
+ sudo yum install pcre-devel
21
+ ```
22
+
4
23
  ## Installation
5
24
  gem install ruby_speech
6
25
 
26
+ ## Ruby Version Compatability
27
+ * CRuby 1.9.3+ (1.9.2 is unofficially supported, but not regularly tested)
28
+ * JRuby 1.7+
29
+
7
30
  ## Library
8
31
 
9
32
  ### SSML
@@ -2,6 +2,8 @@ require 'mkmf'
2
2
 
3
3
  $LIBS << " -lpcre"
4
4
 
5
- abort "-----\n#{lib} is missing.\n-----" unless find_header('pcre.h')
5
+ unless find_header('pcre.h')
6
+ abort "-----\nPCRE is missing. You must install it as per the README @ https://github.com/benlangfeld/ruby_speech\n-----"
7
+ end
6
8
 
7
9
  create_makefile 'ruby_speech/ruby_speech'
@@ -33,12 +33,15 @@ static int is_match_end(pcre *compiled_regex, const char *input)
33
33
  char search_input[MAX_INPUT_SIZE + 2];
34
34
  const char *search_set = "0123456789#*ABCD";
35
35
  const char *search = strchr(search_set, input[input_size - 1]); /* start with last digit in input */
36
+ int i;
36
37
 
37
38
  /* For each digit in search_set, check if input + search_set digit is a potential match.
38
39
  If so, then this is not a match end.
39
40
  */
41
+ if (strlen(input) > MAX_INPUT_SIZE) {
42
+ return 0;
43
+ }
40
44
  sprintf(search_input, "%sZ", input);
41
- int i;
42
45
  for (i = 0; i < 16; i++) {
43
46
  int result;
44
47
  if (!*search) {
data/lib/ruby_speech.rb CHANGED
@@ -1,24 +1,13 @@
1
1
  %w{
2
- active_support/dependencies/autoload
3
- active_support/core_ext/object/blank
4
- active_support/core_ext/numeric/time
5
- active_support/core_ext/enumerable
6
- niceogiri
2
+ nokogiri
3
+
4
+ ruby_speech/version
5
+ ruby_speech/ssml
6
+ ruby_speech/grxml
7
+ ruby_speech/nlsml
7
8
  }.each { |f| require f }
8
9
 
9
10
  module RubySpeech
10
- extend ActiveSupport::Autoload
11
-
12
- autoload :Version
13
-
14
- eager_autoload do
15
- autoload :GenericElement
16
- autoload :SSML
17
- autoload :GRXML
18
- autoload :NLSML
19
- autoload :XML
20
- end
21
-
22
11
  def self.parse(string)
23
12
  document = Nokogiri::XML.parse string, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS
24
13
  namespace = document.root.namespace
@@ -32,5 +21,3 @@ module RubySpeech
32
21
  end
33
22
  end
34
23
  end
35
-
36
- ActiveSupport::Autoload.eager_autoload!
@@ -41,34 +41,42 @@ module RubySpeech
41
41
  # @param [XML::Node] node the node to import
42
42
  # @return the appropriate object based on the node name and namespace
43
43
  def import(node)
44
- node = Nokogiri::XML.parse(node, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS).root unless node.is_a?(Nokogiri::XML::Node)
44
+ node = Nokogiri::XML.parse(node, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS).root unless node.is_a?(Nokogiri::XML::Node) || node.is_a?(GenericElement)
45
45
  return node.content if node.is_a?(Nokogiri::XML::Text)
46
46
  klass = class_from_registration node.node_name
47
47
  if klass && klass != self
48
48
  klass.import node
49
49
  else
50
- new.inherit node
50
+ new(node.document).inherit node
51
51
  end
52
52
  end
53
+ end
53
54
 
54
- def new(atts = {}, &block)
55
- super(self.registered_name, nil, self.namespace) do |new_node|
56
- (self.defaults || {}).merge(atts).each_pair { |k, v| new_node.send :"#{k}=", v }
57
- block_return = new_node.eval_dsl_block &block
58
- new_node.string block_return if block_return.is_a?(String) && block_return.present?
59
- end
60
- end
55
+ def initialize(doc, atts = nil, &block)
56
+ @doc = doc
57
+ build atts, &block if atts || block_given?
61
58
  end
62
59
 
63
60
  attr_writer :parent
64
61
 
62
+ def node
63
+ @node || create_node
64
+ end
65
+
65
66
  def parent
66
67
  @parent || super
67
68
  end
68
69
 
69
70
  def inherit(node)
70
71
  self.parent = node.parent
71
- super
72
+ @node = node
73
+ self
74
+ end
75
+
76
+ def build(atts, &block)
77
+ mass_assign atts
78
+ block_return = eval_dsl_block &block
79
+ string block_return if block_return.is_a?(String) && !block_return.length.zero?
72
80
  end
73
81
 
74
82
  def version
@@ -94,9 +102,16 @@ module RubySpeech
94
102
  end
95
103
 
96
104
  def +(other)
97
- self.class.new(:base_uri => base_uri).tap do |new_element|
98
- (self.children + other.children).each do |child|
99
- new_element << child
105
+ new_doc = Nokogiri::XML::Document.new
106
+ self.class.new(new_doc).tap do |new_element|
107
+ new_doc.root = new_element.node
108
+ if Nokogiri.jruby?
109
+ new_element.add_child self.nokogiri_children
110
+ new_element.add_child other.nokogiri_children
111
+ else
112
+ # TODO: This is yucky because it requires serialization
113
+ new_element.add_child self.nokogiri_children.to_xml
114
+ new_element.add_child other.nokogiri_children.to_xml
100
115
  end
101
116
  end
102
117
  end
@@ -113,15 +128,30 @@ module RubySpeech
113
128
  expression << type.to_s
114
129
 
115
130
  expression << '[' << attributes.inject([]) do |h, (key, value)|
116
- h << "@#{namespace_href && Nokogiri.jruby? ? 'ns:' : ''}#{key}='#{value}'"
131
+ h << "@#{key}='#{value}'"
117
132
  end.join(',') << ']' if attributes
118
133
 
119
- xpath expression, :ns => namespace_href
134
+ xpath expression, :ns => self.class.namespace
120
135
  else
121
136
  super()
122
137
  end.map { |c| self.class.import c }
123
138
  end
124
139
 
140
+ def nokogiri_children
141
+ node.children
142
+ end
143
+
144
+ def <<(other)
145
+ case other
146
+ when GenericElement
147
+ super other.node
148
+ when String
149
+ string other
150
+ else
151
+ super other
152
+ end
153
+ end
154
+
125
155
  def embed(other)
126
156
  case other
127
157
  when String
@@ -141,18 +171,6 @@ module RubySpeech
141
171
  self << Nokogiri::XML::Text.new(other, document)
142
172
  end
143
173
 
144
- def method_missing(method_name, *args, &block)
145
- const_name = method_name.to_s.sub('ssml', '').titleize.gsub(' ', '')
146
- if self.class.module.const_defined?(const_name)
147
- const = self.class.module.const_get const_name
148
- embed const.new(*args, &block)
149
- elsif @block_binding && @block_binding.respond_to?(method_name)
150
- @block_binding.send method_name, *args, &block
151
- else
152
- super
153
- end
154
- end
155
-
156
174
  def clone
157
175
  GRXML.import to_xml
158
176
  end
@@ -162,8 +180,102 @@ module RubySpeech
162
180
  block.call self
163
181
  end
164
182
 
165
- def eql?(o, *args)
166
- super o, :content, :children, *args
183
+ # Helper method to read an attribute
184
+ #
185
+ # @param [#to_sym] attr_name the name of the attribute
186
+ # @param [String, Symbol, nil] to_call the name of the method to call on
187
+ # the returned value
188
+ # @return nil or the value
189
+ def read_attr(attr_name, to_call = nil)
190
+ val = self[attr_name]
191
+ val && to_call ? val.__send__(to_call) : val
192
+ end
193
+
194
+ # Helper method to write a value to an attribute
195
+ #
196
+ # @param [#to_sym] attr_name the name of the attribute
197
+ # @param [#to_s] value the value to set the attribute to
198
+ def write_attr(attr_name, value, to_call = nil)
199
+ self[attr_name] = value && to_call ? value.__send__(to_call) : value
200
+ end
201
+
202
+ # Attach a namespace to the node
203
+ #
204
+ # @overload namespace=(ns)
205
+ # Attach an already created XML::Namespace
206
+ # @param [XML::Namespace] ns the namespace object
207
+ # @overload namespace=(ns)
208
+ # Create a new namespace and attach it
209
+ # @param [String] ns the namespace uri
210
+ def namespace=(namespaces)
211
+ case namespaces
212
+ when Nokogiri::XML::Namespace
213
+ super namespaces
214
+ when String
215
+ ns = self.add_namespace nil, namespaces
216
+ super ns
217
+ end
218
+ end
219
+
220
+ # Helper method to get the node's namespace
221
+ #
222
+ # @return [XML::Namespace, nil] The node's namespace object if it exists
223
+ def namespace_href
224
+ namespace.href if namespace
225
+ end
226
+
227
+ # The node as XML
228
+ #
229
+ # @return [String] XML representation of the node
230
+ def inspect
231
+ self.to_xml
232
+ end
233
+
234
+ def to_s
235
+ to_xml
236
+ end
237
+
238
+ # Check that a set of fields are equal between nodes
239
+ #
240
+ # @param [Node] other the other node to compare against
241
+ # @param [*#to_s] fields the set of fields to compare
242
+ # @return [Fixnum<-1,0,1>]
243
+ def eql?(o, *fields)
244
+ o.is_a?(self.class) && ([:content, :children] + fields).all? { |f| self.__send__(f) == o.__send__(f) }
245
+ end
246
+
247
+ # @private
248
+ def ==(o)
249
+ eql?(o)
250
+ end
251
+
252
+ def create_node
253
+ @node = Nokogiri::XML::Node.new self.class.registered_name, @doc
254
+ mass_assign self.class.defaults
255
+ @node
256
+ end
257
+
258
+ def mass_assign(attrs)
259
+ attrs.each_pair { |k, v| send :"#{k}=", v } if attrs
260
+ end
261
+
262
+ def method_missing(method_name, *args, &block)
263
+ if node.respond_to?(method_name)
264
+ return node.send method_name, *args, &block
265
+ end
266
+
267
+ const_name = method_name.to_s.sub('ssml_', '').gsub('_', '-')
268
+ if const = self.class.class_from_registration(const_name)
269
+ embed const.new(self.document, *args, &block)
270
+ elsif @block_binding && @block_binding.respond_to?(method_name)
271
+ @block_binding.send method_name, *args, &block
272
+ else
273
+ super
274
+ end
275
+ end
276
+
277
+ def respond_to_missing?(method_name, include_private = false)
278
+ node.respond_to?(method_name, include_private) || super
167
279
  end
168
280
  end # Element
169
281
  end # RubySpeech
@@ -1,30 +1,26 @@
1
+ require 'ruby_speech/grxml/matcher'
2
+ require 'ruby_speech/grxml/element'
3
+
1
4
  module RubySpeech
2
5
  module GRXML
3
- extend ActiveSupport::Autoload
4
-
5
- eager_autoload do
6
- autoload :Element
7
- autoload :Grammar
8
- autoload :Rule
9
- autoload :Item
10
- autoload :OneOf
11
- autoload :Ruleref
12
- autoload :Tag
13
- autoload :Token
14
- end
15
-
16
- autoload :Match
17
- autoload :Matcher
18
- autoload :MaxMatch
19
- autoload :NoMatch
20
- autoload :PotentialMatch
21
-
22
6
  InvalidChildError = Class.new StandardError
23
7
 
24
8
  GRXML_NAMESPACE = 'http://www.w3.org/2001/06/grammar'
25
9
 
10
+ %w{
11
+ grammar
12
+ rule
13
+ item
14
+ one_of
15
+ ruleref
16
+ tag
17
+ token
18
+ }.each { |f| require "ruby_speech/grxml/#{f}" }
19
+
26
20
  def self.draw(attributes = {}, &block)
27
- Grammar.new(attributes).tap do |grammar|
21
+ document = Nokogiri::XML::Document.new
22
+ Grammar.new(document, attributes).tap do |grammar|
23
+ document.root = grammar.node
28
24
  block_return = grammar.eval_dsl_block &block
29
25
  grammar << block_return if block_return.is_a?(String)
30
26
  end.assert_has_matching_root_rule
@@ -35,5 +31,3 @@ module RubySpeech
35
31
  end
36
32
  end # GRXML
37
33
  end # RubySpeech
38
-
39
- ActiveSupport::Autoload.eager_autoload!
@@ -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 GRXML
5
- class Element < Niceogiri::XML::Node
5
+ class Element
6
6
  def self.namespace
7
7
  GRXML_NAMESPACE
8
8
  end
@@ -15,12 +15,12 @@ module RubySpeech
15
15
  GRXML
16
16
  end
17
17
 
18
- alias_method :nokogiri_children, :children
19
-
20
- alias :to_doc :document
21
-
22
18
  include GenericElement
23
19
 
20
+ def to_doc
21
+ document
22
+ end
23
+
24
24
  def regexp_content # :nodoc:
25
25
  "(#{children.map(&:regexp_content).join})"
26
26
  end