ruby_speech 2.3.1-java → 3.0.1-java

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 (60) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.hound.yml +2 -0
  4. data/.travis.yml +25 -9
  5. data/CHANGELOG.md +19 -1
  6. data/README.md +14 -15
  7. data/Rakefile +2 -0
  8. data/ext/ruby_speech/RubySpeechGRXMLMatcher.java +17 -12
  9. data/ext/ruby_speech/RubySpeechService.java +1 -1
  10. data/ext/ruby_speech/extconf.rb +1 -1
  11. data/lib/ruby_speech/generic_element.rb +2 -2
  12. data/lib/ruby_speech/grxml/builtins.rb +18 -11
  13. data/lib/ruby_speech/grxml/grammar.rb +26 -4
  14. data/lib/ruby_speech/grxml/matcher.rb +2 -2
  15. data/lib/ruby_speech/grxml.rb +2 -0
  16. data/lib/ruby_speech/nlsml/builder.rb +2 -1
  17. data/lib/ruby_speech/nlsml/document.rb +5 -0
  18. data/lib/ruby_speech/ruby_speech.jar +0 -0
  19. data/lib/ruby_speech/ssml/break.rb +1 -2
  20. data/lib/ruby_speech/ssml/element.rb +13 -1
  21. data/lib/ruby_speech/ssml/mark.rb +0 -1
  22. data/lib/ruby_speech/ssml/prosody.rb +8 -5
  23. data/lib/ruby_speech/version.rb +1 -1
  24. data/ruby_speech.gemspec +13 -8
  25. data/spec/ruby_speech/grxml/builtins_spec.rb +80 -71
  26. data/spec/ruby_speech/grxml/grammar_spec.rb +168 -34
  27. data/spec/ruby_speech/grxml/item_spec.rb +33 -33
  28. data/spec/ruby_speech/grxml/match_spec.rb +1 -1
  29. data/spec/ruby_speech/grxml/matcher_spec.rb +103 -59
  30. data/spec/ruby_speech/grxml/max_match_spec.rb +2 -2
  31. data/spec/ruby_speech/grxml/no_match_spec.rb +2 -2
  32. data/spec/ruby_speech/grxml/one_of_spec.rb +6 -6
  33. data/spec/ruby_speech/grxml/potential_match_spec.rb +2 -2
  34. data/spec/ruby_speech/grxml/rule_spec.rb +17 -17
  35. data/spec/ruby_speech/grxml/ruleref_spec.rb +10 -10
  36. data/spec/ruby_speech/grxml/tag_spec.rb +5 -5
  37. data/spec/ruby_speech/grxml/token_spec.rb +7 -7
  38. data/spec/ruby_speech/grxml_spec.rb +25 -25
  39. data/spec/ruby_speech/nlsml_spec.rb +58 -10
  40. data/spec/ruby_speech/ssml/audio_spec.rb +19 -19
  41. data/spec/ruby_speech/ssml/break_spec.rb +42 -22
  42. data/spec/ruby_speech/ssml/desc_spec.rb +7 -7
  43. data/spec/ruby_speech/ssml/emphasis_spec.rb +21 -21
  44. data/spec/ruby_speech/ssml/mark_spec.rb +5 -5
  45. data/spec/ruby_speech/ssml/p_spec.rb +17 -17
  46. data/spec/ruby_speech/ssml/phoneme_spec.rb +8 -8
  47. data/spec/ruby_speech/ssml/prosody_spec.rb +82 -64
  48. data/spec/ruby_speech/ssml/s_spec.rb +16 -16
  49. data/spec/ruby_speech/ssml/say_as_spec.rb +9 -9
  50. data/spec/ruby_speech/ssml/speak_spec.rb +29 -29
  51. data/spec/ruby_speech/ssml/sub_spec.rb +7 -7
  52. data/spec/ruby_speech/ssml/voice_spec.rb +31 -31
  53. data/spec/ruby_speech/ssml_spec.rb +41 -17
  54. data/spec/ruby_speech_spec.rb +3 -3
  55. data/spec/spec_helper.rb +8 -3
  56. data/spec/support/dtmf_helper.rb +14 -0
  57. data/spec/support/grammar_matchers.rb +6 -6
  58. data/spec/support/match_examples.rb +5 -5
  59. data/spec/support/matchers.rb +1 -1
  60. metadata +109 -80
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2392c6cf73b13b54d94cd854f0b58cf4787356f1
4
- data.tar.gz: cf5c6d4c8d537416c6389974237b5b965a898d25
2
+ SHA256:
3
+ metadata.gz: bf0ce7a02ac2402dc159a5888b4d1fdbcc670cc78a34a25bbd666257a3fc40c0
4
+ data.tar.gz: a81459d60d6d3af6cbcf18fbcad2e12b9c54a23270da08342036635c3e527b28
5
5
  SHA512:
6
- metadata.gz: 7aeeeeb1b5bf64c26f936f29e2df02b4c9198340efa535dd403429aaabbc753a98c03bc27178c4f3e58dab13affd13456d5064b7562549b7e48dba3a185213a2
7
- data.tar.gz: ade7291fd515e30ea1ca77d76a6fc59878687a6c985e724a2b00add1b8cfeebf4cf897a6eadb057c05b464138f7d0504060faca40d327b2e4c382540a448eb17
6
+ metadata.gz: 42b2d1512761f1f0d8ea24ec610a8bb04a7e4af7440fc80faf981a088518fbd60944146859f8c4538971b9b63dad81a646f7e29d2cb53f18ec3a4a2bf29a54f0
7
+ data.tar.gz: f6efa7172c52f12d59f5979b400500d02d79036ec13896e4593d6913da24407420b3c7949bc06f07cbe947ec525eb2a7ea9d78387941259b932afe97710c0a26
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  *.gem
3
3
  *.bundle
4
4
  *.jar
5
+ *.so
5
6
  Gemfile.lock
6
7
  pkg/*
7
8
  spec/reports
data/.hound.yml ADDED
@@ -0,0 +1,2 @@
1
+ LineLength:
2
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,17 +1,33 @@
1
+ dist: xenial
1
2
  language: ruby
2
-
3
3
  rvm:
4
- - 1.9.3
5
- - 2.0.0
6
- - 2.1.0
7
- - jruby-19mode
8
- - rbx-19mode
4
+ - 2.1.10
5
+ - 2.2.10
6
+ - 2.3.8
7
+ - 2.4.5
8
+ - 2.5.3
9
+ - 2.6.3
10
+ - jruby-9.1.17.0
11
+ - jruby-head
9
12
  - ruby-head
13
+ jdk:
14
+ - openjdk8 # for jruby
10
15
  matrix:
16
+ include:
17
+ - rvm: rbx-4
18
+ dist: trusty
19
+ name: Rubinius
11
20
  allow_failures:
21
+ - name: Rubinius
12
22
  - rvm: ruby-head
13
- before_install:
14
- - sudo apt-get install libpcre3 libpcre3-dev
15
-
23
+ addons:
24
+ apt:
25
+ packages:
26
+ - libpcre3
27
+ - libpcre3-dev
28
+ env:
29
+ global:
30
+ - JRUBY_OPTS='--debug'
31
+ before_install: rvm list
16
32
  notifications:
17
33
  irc: "irc.freenode.org#adhearsion"
data/CHANGELOG.md CHANGED
@@ -1,4 +1,22 @@
1
- # [develop](https://github.com/benlangfeld/ruby_speech)
1
+ # [3.0.1](https://github.com/benlangfeld/ruby_speech/compare/v3.0.0...v3.0.1) - [2022-02-15](https://rubygems.org/gems/ruby_speech/versions/3.0.1)
2
+ * Misc: Relax dependency limits to allow newer ActiveSupport versions and thus Ruby 3.0
3
+ * Bugfix: Misc performance improvements
4
+
5
+ # [3.0.0](https://github.com/benlangfeld/ruby_speech/compare/v2.4.0...v3.0.0) - [2018-07-10](https://rubygems.org/gems/ruby_speech/versions/3.0.0)
6
+ * Feature: Loosen and bump Nokogiri version to ~>1.8, >=1.8.3
7
+ * Feature: Bump RSpec to 3.x and convert specs with Transpec
8
+
9
+ # [2.4.0](https://github.com/benlangfeld/ruby_speech/compare/v2.3.2...v2.4.0) - [2018-02-23](https://rubygems.org/gems/ruby_speech/versions/2.4.0)
10
+ * Feature: Permit percentage rate values for prosody tags
11
+ * Bugfix: Rulerefs referenced n-levels deep under Rulerefs should be expanded.
12
+ * Bugfix: Optimize performance of built-in number DTMF grammar
13
+ * Bugfix: Fix handling of millisecond values
14
+
15
+ # [2.3.2](https://github.com/benlangfeld/ruby_speech/compare/v2.3.1...v2.3.2) - [2014-04-21](https://rubygems.org/gems/ruby_speech/versions/2.3.2)
16
+ * Bugfix: String nodes should take non-strings and cast to a string (`#to_s`)
17
+ * Bugfix: Cleanly handle NLSML with no input tag
18
+ * Bugfix: Drawing an NLSML doc should return something structured/parsed
19
+ * Bugfix: Cloning SSML documents no longer turns them into GRXML docs
2
20
 
3
21
  # [2.3.1](https://github.com/benlangfeld/ruby_speech/compare/v2.3.0...v2.3.1) - [2014-02-24](https://rubygems.org/gems/ruby_speech/versions/2.3.1)
4
22
  * Bugfix: Phone number grammar should only allow a single instance of '*'/'x'
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
- [![Gem Version](https://badge.fury.io/rb/ruby_speech.png)](https://rubygems.org/gems/ruby_speech)
2
- [![Build Status](https://secure.travis-ci.org/benlangfeld/ruby_speech.png?branch=develop)](http://travis-ci.org/benlangfeld/ruby_speech)
3
- [![Dependency Status](https://gemnasium.com/benlangfeld/ruby_speech.png?travis)](https://gemnasium.com/benlangfeld/ruby_speech)
4
- [![Code Climate](https://codeclimate.com/github/benlangfeld/ruby_speech.png)](https://codeclimate.com/github/benlangfeld/ruby_speech)
5
- [![Coverage Status](https://coveralls.io/repos/benlangfeld/ruby_speech/badge.png?branch=develop)](https://coveralls.io/r/benlangfeld/ruby_speech)
1
+ [![Gem Version](https://badge.fury.io/rb/ruby_speech.svg)](https://rubygems.org/gems/ruby_speech)
2
+ [![Build Status](https://secure.travis-ci.org/adhearsion/ruby_speech.svg?branch=develop)](http://travis-ci.org/adhearsion/ruby_speech)
3
+ [![Code Climate](https://codeclimate.com/github/adhearsion/ruby_speech.svg)](https://codeclimate.com/github/adhearsion/ruby_speech)
4
+ [![Coverage Status](https://coveralls.io/repos/adhearsion/ruby_speech/badge.svg?branch=develop)](https://coveralls.io/r/adhearsion/ruby_speech)
6
5
 
7
6
  # RubySpeech
8
7
  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.
@@ -30,8 +29,8 @@ sudo yum install pcre-devel
30
29
  gem install ruby_speech
31
30
 
32
31
  ## Ruby Version Compatability
33
- * CRuby 1.9.3+ (1.9.2 is unofficially supported, but not regularly tested)
34
- * JRuby 1.7+
32
+ * CRuby 2.1+
33
+ * JRuby 9.1+
35
34
 
36
35
  ## Library
37
36
 
@@ -259,7 +258,7 @@ require 'ruby_speech'
259
258
 
260
259
  nlsml = RubySpeech::NLSML.draw grammar: 'http://flight' do
261
260
  interpretation confidence: 0.6 do
262
- input "I want to go to Pittsburgh", mode: :speech
261
+ input "I want to go to Pittsburgh", mode: :voice
263
262
 
264
263
  instance do
265
264
  airline do
@@ -288,7 +287,7 @@ becomes:
288
287
  <?xml version="1.0"?>
289
288
  <result xmlns="http://www.ietf.org/xml/ns/mrcpv2" grammar="http://flight">
290
289
  <interpretation confidence="0.6">
291
- <input mode="speech">I want to go to Pittsburgh</input>
290
+ <input mode="voice">I want to go to Pittsburgh</input>
292
291
  <instance>
293
292
  <airline>
294
293
  <to_city>Pittsburgh</to_city>
@@ -315,7 +314,7 @@ document.match? # => true
315
314
  document.interpretations # => [
316
315
  {
317
316
  confidence: 0.6,
318
- input: { mode: :speech, content: 'I want to go to Pittsburgh' },
317
+ input: { mode: :voice, content: 'I want to go to Pittsburgh' },
319
318
  instance: { airline: { to_city: 'Pittsburgh' } }
320
319
  },
321
320
  {
@@ -326,12 +325,12 @@ document.interpretations # => [
326
325
  ]
327
326
  document.best_interpretation # => {
328
327
  confidence: 0.6,
329
- input: { mode: :speech, content: 'I want to go to Pittsburgh' },
328
+ input: { mode: :voice, content: 'I want to go to Pittsburgh' },
330
329
  instance: { airline: { to_city: 'Pittsburgh' } }
331
330
  }
332
331
  ```
333
332
 
334
- Check out the [YARD documentation](http://rdoc.info/github/benlangfeld/ruby_speech/master/frames) for more
333
+ Check out the [YARD documentation](http://rdoc.info/github/adhearsion/ruby_speech/master/frames) for more
335
334
 
336
335
  ## Features:
337
336
  ### SSML
@@ -374,10 +373,10 @@ Check out the [YARD documentation](http://rdoc.info/github/benlangfeld/ruby_spee
374
373
  * `<lexicon/>`
375
374
 
376
375
  ## Links:
377
- * [Source](https://github.com/benlangfeld/ruby_speech)
376
+ * [Source](https://github.com/adhearsion/ruby_speech)
378
377
  * [Documentation](http://rdoc.info/gems/ruby_speech/frames)
379
- * [Bug Tracker](https://github.com/benlangfeld/ruby_speech/issues)
380
- * [CI](https://travis-ci.org/#!/benlangfeld/ruby_speech)
378
+ * [Bug Tracker](https://github.com/adhearsion/ruby_speech/issues)
379
+ * [CI](https://travis-ci.org/#!/adhearsion/ruby_speech)
381
380
 
382
381
  ## Note on Patches/Pull Requests
383
382
 
data/Rakefile CHANGED
@@ -25,6 +25,8 @@ if RUBY_PLATFORM =~ /java/
25
25
  require 'rake/javaextensiontask'
26
26
  Rake::JavaExtensionTask.new 'ruby_speech' do |ext|
27
27
  ext.lib_dir = 'lib/ruby_speech'
28
+ ext.source_version = '1.6'
29
+ ext.target_version = '1.6'
28
30
  end
29
31
  else
30
32
  require 'rake/extensiontask'
@@ -1,4 +1,4 @@
1
- package com.benlangfeld.ruby_speech;
1
+ package com.adhearsion.ruby_speech;
2
2
 
3
3
  import org.jruby.Ruby;
4
4
  import org.jruby.RubyClass;
@@ -6,6 +6,7 @@ import org.jruby.RubyModule;
6
6
  import org.jruby.RubyObject;
7
7
  import org.jruby.anno.JRubyClass;
8
8
  import org.jruby.anno.JRubyMethod;
9
+ import org.jruby.runtime.Block;
9
10
  import org.jruby.runtime.ObjectAllocator;
10
11
  import org.jruby.runtime.ThreadContext;
11
12
  import org.jruby.runtime.Visibility;
@@ -43,22 +44,26 @@ public class RubySpeechGRXMLMatcher extends RubyObject {
43
44
  }
44
45
  return callMethod(context, "match_for_buffer", buffer);
45
46
  } else if (m.hitEnd()) {
46
- RubyModule potential_match = runtime.getClassFromPath("RubySpeech::GRXML::PotentialMatch");
47
- return potential_match.callMethod(context, "new");
47
+ return getGRXMLType(runtime, "PotentialMatch").newInstance(context, Block.NULL_BLOCK);
48
48
  }
49
- RubyModule nomatch = runtime.getClassFromPath("RubySpeech::GRXML::NoMatch");
50
- return nomatch.callMethod(context, "new");
49
+ return getGRXMLType(runtime, "NoMatch").newInstance(context, Block.NULL_BLOCK);
51
50
  }
52
51
 
53
- public Boolean is_max_match(String buffer)
54
- {
55
- String search_set = "0123456789#*ABCD";
56
- for (int i = 0; i < 16; i++) {
57
- String new_buffer = buffer + search_set.charAt(i);
58
- Matcher m = p.matcher(new_buffer);
59
- if (m.matches()) return false;
52
+ private boolean is_max_match(String buffer) {
53
+ final int len = buffer.length();
54
+ StringBuilder new_buffer = new StringBuilder(len + 1);
55
+ new_buffer.append(buffer).append('\0');
56
+ final String search_set = "0123456789#*ABCD";
57
+ for (int i = 0; i < search_set.length(); i++) {
58
+ new_buffer.setCharAt(len, search_set.charAt(i));
59
+ if (p.matcher(new_buffer).matches()) return false;
60
60
  }
61
61
  return true;
62
62
  }
63
63
 
64
+ private static RubyClass getGRXMLType(final Ruby runtime, final String name) {
65
+ RubyModule grxml = (RubyModule) runtime.getModule("RubySpeech").getConstantAt("GRXML");
66
+ return (RubyClass) grxml.getConstantAt(name);
67
+ }
68
+
64
69
  }
@@ -1,4 +1,4 @@
1
- package com.benlangfeld.ruby_speech;
1
+ package com.adhearsion.ruby_speech;
2
2
 
3
3
  import org.jruby.Ruby;
4
4
  import org.jruby.RubyClass;
@@ -3,7 +3,7 @@ require 'mkmf'
3
3
  $LIBS << " -lpcre"
4
4
 
5
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-----"
6
+ abort "-----\nPCRE is missing. You must install it as per the README @ https://github.com/adhearsion/ruby_speech\n-----"
7
7
  end
8
8
 
9
9
  create_makefile 'ruby_speech/ruby_speech'
@@ -172,11 +172,11 @@ module RubySpeech
172
172
  end
173
173
 
174
174
  def string(other)
175
- self << Nokogiri::XML::Text.new(other, document)
175
+ self << Nokogiri::XML::Text.new(other.to_s, document)
176
176
  end
177
177
 
178
178
  def clone
179
- GRXML.import to_xml
179
+ self.class.import to_xml
180
180
  end
181
181
 
182
182
  def traverse(&block)
@@ -57,7 +57,8 @@ module RubySpeech::GRXML::Builtins
57
57
  # @option options [#to_i] :maxlength Maximum length for the string of digits.
58
58
  # @option options [#to_i] :length Absolute length for the string of digits.
59
59
  #
60
- # @return [RubySpeech::GRXML::Grammar] a grammar for interpreting a boolean response.
60
+ # @return [RubySpeech::GRXML::Grammar] a grammar for interpreting an integer
61
+ # response.
61
62
  #
62
63
  # @raise [ArgumentError] if any of the length attributes logically conflict
63
64
  #
@@ -118,22 +119,28 @@ module RubySpeech::GRXML::Builtins
118
119
  def self.number(options = nil)
119
120
  RubySpeech::GRXML.draw mode: :dtmf, root: 'number' do
120
121
  rule id: 'number', scope: 'public' do
121
- item repeat: '0-' do
122
- ruleref uri: '#digit'
122
+ one_of do
123
+ item { ruleref uri: '#less_than_one' }
124
+ item { ruleref uri: '#one_or_more' }
123
125
  end
126
+ end
127
+
128
+ rule id: 'less_than_one' do
129
+ item { '*' }
130
+ item { ruleref uri: '#digit_series' }
131
+ end
132
+
133
+ rule id: 'one_or_more' do
134
+ item { ruleref uri: '#digit_series' }
124
135
  item repeat: '0-1' do
125
136
  item { '*' }
126
- item repeat: '0-' do
127
- ruleref uri: '#digit'
128
- end
137
+ item(repeat: '0-1') { ruleref uri: '#digit_series' }
129
138
  end
130
139
  end
131
140
 
132
- rule id: 'digit' do
133
- one_of do
134
- 0.upto(9) { |d| item { d.to_s } }
135
- end
136
- end
141
+ rule(id: 'digit_series') { item(repeat: '1-') { ruleref uri: '#digit' } }
142
+
143
+ rule(id: 'digit') { one_of { 0.upto(9) { |d| item { d.to_s } } } }
137
144
  end
138
145
  end
139
146
 
@@ -113,17 +113,39 @@ module RubySpeech
113
113
  # Replaces rulerefs in the document with a copy of the original rule.
114
114
  # Removes all top level rules except the root rule
115
115
  #
116
+ # @raises [MissingReferenceError] if a ruleref references a rule that is
117
+ # not defined.
118
+ # @raises [ReferentialLoopError] if rulerefs create a referencial cycle.
119
+ #
116
120
  # @return self
117
121
  #
118
122
  def inline!
119
- xpath("//ns:ruleref", :ns => GRXML_NAMESPACE).each do |ref|
120
- rule = rule_with_id ref[:uri].sub(/^#/, '')
121
- ref.swap rule.dup.children
123
+ previous_uris = {}
124
+ loop do
125
+ rule = nil
126
+ uris = {}
127
+ xpath('//ns:ruleref', ns: GRXML_NAMESPACE).each do |ref|
128
+ uri = ref[:uri].sub(/^#/, '')
129
+ uris[uri] = 1
130
+ rule = rule_with_id uri
131
+ unless rule
132
+ raise MissingReferenceError,
133
+ "Ruleref '##{uri}' is referenced but not defined"
134
+ end
135
+ ref.swap rule.dup.children
136
+ end
137
+ break unless rule
138
+ if previous_uris.keys.eql? uris.keys
139
+ raise ReferentialLoopError,
140
+ 'GRXML document contains cycles with ruleref(s): ' <<
141
+ uris.keys.join(', ')
142
+ end
143
+ previous_uris = uris
122
144
  end
123
145
 
124
146
  query = "./ns:rule[@id!='#{root}']"
125
147
  query += "|./ns:rule[@ns:id!='#{root}']" if Nokogiri.jruby?
126
- non_root_rules = xpath query, :ns => namespace_href
148
+ non_root_rules = xpath query, ns: namespace_href
127
149
  non_root_rules.remove
128
150
 
129
151
  self
@@ -6,7 +6,7 @@ require 'ruby_speech/ruby_speech'
6
6
 
7
7
  if RUBY_PLATFORM =~ /java/
8
8
  require 'jruby'
9
- com.benlangfeld.ruby_speech.RubySpeechService.new.basicLoad(JRuby.runtime)
9
+ com.adhearsion.ruby_speech.RubySpeechService.new.basicLoad(JRuby.runtime)
10
10
  end
11
11
 
12
12
  module RubySpeech
@@ -90,7 +90,7 @@ module RubySpeech
90
90
  # ```
91
91
  #
92
92
  def match(buffer)
93
- find_match buffer.dup
93
+ find_match buffer
94
94
  end
95
95
 
96
96
  private
@@ -4,6 +4,8 @@ require 'ruby_speech/grxml/element'
4
4
  module RubySpeech
5
5
  module GRXML
6
6
  InvalidChildError = Class.new StandardError
7
+ MissingReferenceError = Class.new StandardError
8
+ ReferentialLoopError = Class.new StandardError
7
9
 
8
10
  GRXML_NAMESPACE = 'http://www.w3.org/2001/06/grammar'
9
11
 
@@ -5,11 +5,12 @@ module RubySpeech
5
5
 
6
6
  def initialize(options = {}, &block)
7
7
  options = {'xmlns' => NLSML_NAMESPACE}.merge(options)
8
- @document = Nokogiri::XML::Builder.new do |builder|
8
+ xml_doc = Nokogiri::XML::Builder.new do |builder|
9
9
  builder.result options do |r|
10
10
  apply_block r, &block
11
11
  end
12
12
  end.doc
13
+ @document = RubySpeech::NLSML::Document.new xml_doc
13
14
  end
14
15
 
15
16
  def interpretation(*args, &block)
@@ -38,6 +38,10 @@ module RubySpeech
38
38
  noinput_elements.any?
39
39
  end
40
40
 
41
+ def to_xml
42
+ document.to_xml
43
+ end
44
+
41
45
  private
42
46
 
43
47
  def nomatch?
@@ -58,6 +62,7 @@ module RubySpeech
58
62
 
59
63
  def input_hash_for_interpretation(interpretation)
60
64
  input_element = interpretation.at_xpath 'ns:input', 'ns' => NLSML_NAMESPACE
65
+ return unless input_element
61
66
  { content: input_element.content }.tap do |h|
62
67
  h[:mode] = input_element['mode'].to_sym if input_element['mode']
63
68
  end
Binary file
@@ -36,7 +36,7 @@ module RubySpeech
36
36
  # @return [Float]
37
37
  #
38
38
  def time
39
- read_attr :time, :to_f
39
+ get_time_attribute :time
40
40
  end
41
41
 
42
42
  ##
@@ -50,7 +50,6 @@ module RubySpeech
50
50
 
51
51
  def <<(*args)
52
52
  raise InvalidChildError, "A Break cannot contain children"
53
- super
54
53
  end
55
54
 
56
55
  def eql?(o)
@@ -23,9 +23,21 @@ module RubySpeech
23
23
 
24
24
  private
25
25
 
26
+ def get_time_attribute(key)
27
+ value = read_attr(key)
28
+
29
+ if value.nil?
30
+ nil
31
+ elsif value.end_with?('ms')
32
+ value.to_f / 1000
33
+ else
34
+ value.to_f
35
+ end
36
+ end
37
+
26
38
  def set_time_attribute(key, value)
27
39
  raise ArgumentError, "You must specify a valid #{key} (positive float value in seconds)" unless value.is_a?(Numeric) && value >= 0
28
- self[key] = "#{value}s"
40
+ self[key] = value == value.round ? "#{value.to_i}s" : "#{(value * 1000).to_i}ms"
29
41
  end
30
42
  end # Element
31
43
  end # SSML
@@ -34,7 +34,6 @@ module RubySpeech
34
34
 
35
35
  def <<(*args)
36
36
  raise InvalidChildError, "A Mark cannot contain children"
37
- super
38
37
  end
39
38
 
40
39
  def eql?(o)
@@ -102,27 +102,29 @@ module RubySpeech
102
102
  end
103
103
 
104
104
  ##
105
- # A change in the speaking rate for the contained text. Legal values are: a relative change or "x-slow", "slow", "medium", "fast", "x-fast", or "default". Labels "x-slow" through "x-fast" represent a sequence of monotonically non-decreasing speaking rates. When a number is used to specify a relative change it acts as a multiplier of the default rate. For example, a value of 1 means no change in speaking rate, a value of 2 means a speaking rate twice the default rate, and a value of 0.5 means a speaking rate of half the default rate. The default rate for a voice depends on the language and dialect and on the personality of the voice. The default rate for a voice should be such that it is experienced as a normal speaking rate for the voice when reading aloud text. Since voices are processor-specific, the default rate will be as well.
105
+ # A change in the speaking rate for the contained text. Legal values are: a relative change or "x-slow", "slow", "medium", "fast", "x-fast", or "default". Labels "x-slow" through "x-fast" represent a sequence of monotonically non-decreasing speaking rates. When a number is used to specify a relative change it acts as a multiplier of the default rate. For example, a value of 1 means no change in speaking rate, a value of 2 means a speaking rate twice the default rate, and a value of 0.5 means a speaking rate of half the default rate. Further, changes can be specified as percentages (e.g. '10%' or '+15%'), but these are the only string entries permitted. The default rate for a voice depends on the language and dialect and on the personality of the voice. The default rate for a voice should be such that it is experienced as a normal speaking rate for the voice when reading aloud text. Since voices are processor-specific, the default rate will be as well.
106
106
  #
107
- # @return [Symbol, Float]
107
+ # @return [Symbol, Float, String]
108
108
  #
109
109
  def rate
110
110
  value = read_attr :rate
111
111
  return unless value
112
112
  if VALID_RATES.include?(value.to_sym)
113
113
  value.to_sym
114
+ elsif value.include? "%"
115
+ value
114
116
  else
115
117
  value.to_f
116
118
  end
117
119
  end
118
120
 
119
121
  ##
120
- # @param [Symbol, Numeric] v
122
+ # @param [Symbol, Numeric, String] v
121
123
  #
122
124
  # @raises ArgumentError if v is not either a positive Numeric or one of VALID_RATES
123
125
  #
124
126
  def rate=(v)
125
- raise ArgumentError, "You must specify a valid rate ([positive-number](multiplier), #{VALID_RATES.map(&:inspect).join ', '})" unless (v.is_a?(Numeric) && v >= 0) || VALID_RATES.include?(v)
127
+ raise ArgumentError, "You must specify a valid rate ([positive-number](multiplier), #{VALID_RATES.map(&:inspect).join ', '})" unless (v.is_a?(Numeric) && v >= 0) || VALID_RATES.include?(v) || (v.is_a?(String) && v.include?("%"))
126
128
  self[:rate] = v
127
129
  end
128
130
 
@@ -132,7 +134,8 @@ module RubySpeech
132
134
  # @return [Integer]
133
135
  #
134
136
  def duration
135
- read_attr :duration, :to_i
137
+ value = get_time_attribute :duration
138
+ value.round if value
136
139
  end
137
140
 
138
141
  ##
@@ -1,3 +1,3 @@
1
1
  module RubySpeech
2
- VERSION = "2.3.1"
2
+ VERSION = "3.0.1"
3
3
  end
data/ruby_speech.gemspec CHANGED
@@ -7,13 +7,11 @@ Gem::Specification.new do |s|
7
7
  s.version = RubySpeech::VERSION
8
8
  s.authors = ["Ben Langfeld"]
9
9
  s.email = ["ben@langfeld.me"]
10
- s.homepage = "https://github.com/benlangfeld/ruby_speech"
10
+ s.homepage = "https://github.com/adhearsion/ruby_speech"
11
11
  s.summary = %q{A Ruby library for TTS & ASR document preparation}
12
12
  s.description = %q{Prepare SSML and GRXML documents with ease}
13
-
14
- s.license = 'MIT'
15
13
 
16
- s.rubyforge_project = "ruby_speech"
14
+ s.license = 'MIT'
17
15
 
18
16
  s.files = `git ls-files`.split("\n")
19
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -27,18 +25,25 @@ Gem::Specification.new do |s|
27
25
  s.extensions = ['ext/ruby_speech/extconf.rb']
28
26
  end
29
27
 
30
- s.add_runtime_dependency %q<nokogiri>, ["~> 1.6"]
31
- s.add_runtime_dependency %q<activesupport>, [">= 3.0.7", "< 5.0.0"]
28
+ s.add_runtime_dependency %q<nokogiri>, ["~> 1.8", ">= 1.8.3"]
29
+ s.add_runtime_dependency %q<activesupport>, [">= 3.0.7"]
32
30
 
33
31
  s.add_development_dependency %q<bundler>, [">= 1.0.0"]
34
- s.add_development_dependency %q<rspec>, [">= 2.7"]
35
- s.add_development_dependency %q<ci_reporter>, [">= 1.6.3"]
32
+ s.add_development_dependency %q<rspec>, ["~> 3.0"]
33
+ s.add_development_dependency %q<rspec-its>, [">= 0"]
34
+ s.add_development_dependency %q<ci_reporter>, ["~> 1.6"]
36
35
  s.add_development_dependency %q<yard>, [">= 0.7.0"]
37
36
  s.add_development_dependency %q<rake>, [">= 0"]
38
37
  s.add_development_dependency %q<guard>, [">= 0.9.0"]
39
38
  s.add_development_dependency %q<guard-rspec>, [">= 0"]
39
+ s.add_development_dependency %q<listen>, ["< 3.1.0"]
40
40
  s.add_development_dependency %q<ruby_gntp>, [">= 0"]
41
41
  s.add_development_dependency %q<guard-rake>, [">= 0"]
42
42
  s.add_development_dependency %q<rake-compiler>, [">= 0"]
43
43
  s.add_development_dependency %q<coveralls>, [">= 0"]
44
+
45
+ if RUBY_VERSION < '2.0'
46
+ s.add_development_dependency %q<term-ansicolor>, ["< 1.3.1"]
47
+ s.add_development_dependency %q<tins>, ["~> 1.6.0"]
48
+ end
44
49
  end