ruby_speech 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,126 @@
1
+ module RubySpeech
2
+ module GRXML
3
+ ##
4
+ # The Speech Recognition Grammar Language is an XML application. The root element is grammar.
5
+ #
6
+ # http://www.w3.org/TR/speech-grammar/#S4.3
7
+ #
8
+ # Attributes: uri, language, root, tag-format
9
+ #
10
+ # tag-format declaration is an optional declaration of a tag-format identifier that indicates the content type of all tags contained within a grammar.
11
+ #
12
+ # NOTE: A grammar without rules is allowed but cannot be used for processing input -- http://www.w3.org/Voice/2003/srgs-ir/
13
+ #
14
+ # TODO: Look into lexicon (probably a sub element)
15
+ #
16
+ class Grammar < Element
17
+ include XML::Language
18
+
19
+ register :grammar
20
+
21
+ VALID_CHILD_TYPES = [Nokogiri::XML::Element, Nokogiri::XML::Text, Rule, Tag].freeze
22
+
23
+ ##
24
+ # Create a new GRXML grammar root element
25
+ #
26
+ # @param [Hash] atts Key-value pairs of options mapping to setter methods
27
+ #
28
+ # @return [Grammar] an element for use in an GRXML document
29
+ #
30
+ def self.new(atts = {}, &block)
31
+ new_node = super('grammar', atts)
32
+ new_node[:version] = '1.0'
33
+ new_node.namespace = GRXML_NAMESPACE
34
+ new_node.language ||= "en-US"
35
+ new_node.instance_eval &block if block_given?
36
+ new_node
37
+ end
38
+
39
+ ##
40
+ # @return [String] the base URI to which relative URLs are resolved
41
+ #
42
+ def base_uri
43
+ read_attr :base
44
+ end
45
+
46
+ ##
47
+ # @param [String] uri the base URI to which relative URLs are resolved
48
+ #
49
+ def base_uri=(uri)
50
+ write_attr 'xml:base', uri
51
+ end
52
+
53
+ ##
54
+ #
55
+ # The mode of a grammar indicates the type of input that the user agent should be detecting. The default mode is "voice" for speech recognition grammars. An alternative input mode is "dtmf" input".
56
+ #
57
+ # @return [String]
58
+ #
59
+ def mode
60
+ read_attr :mode
61
+ end
62
+
63
+ ##
64
+ # @param [String] ia
65
+ #
66
+ def mode=(ia)
67
+ write_attr :mode, ia
68
+ end
69
+
70
+ ##
71
+ #
72
+ # The root ("rule") attribute indicates declares a single rule to be the root rle of the grammar. This attribute is OPTIONAL. The rule declared must be defined within the scope of the grammar. It specified rule can be scoped "public" or "private."
73
+ #
74
+ # @return [String]
75
+ #
76
+ def root
77
+ read_attr :root
78
+ end
79
+
80
+ ##
81
+ # @param [String] ia
82
+ #
83
+ def root=(ia)
84
+ write_attr :root, ia
85
+ end
86
+
87
+ def <<(arg)
88
+ raise InvalidChildError, "A Grammar can only accept Rule and Tag as children" unless VALID_CHILD_TYPES.include? arg.class
89
+ super
90
+ end
91
+
92
+ def to_doc
93
+ Nokogiri::XML::Document.new.tap do |doc|
94
+ doc << self
95
+ end
96
+ end
97
+
98
+ ##
99
+ #
100
+ # @return [String]
101
+ #
102
+ def tag_format
103
+ read_attr :'tag-format'
104
+ end
105
+
106
+ ##
107
+ # @param [String] ia
108
+ #
109
+ def tag_format=(s)
110
+ write_attr :'tag-format', s
111
+ end
112
+
113
+ def +(other)
114
+ self.class.new(:base_uri => base_uri).tap do |new_grammar|
115
+ (self.children + other.children).each do |child|
116
+ new_grammar << child
117
+ end
118
+ end
119
+ end
120
+
121
+ def eql?(o)
122
+ super o, :language, :base_uri, :mode, :root
123
+ end
124
+ end # Grammar
125
+ end # GRXML
126
+ end # RubySpeech
@@ -0,0 +1,135 @@
1
+ module RubySpeech
2
+ module GRXML
3
+ ##
4
+ #
5
+ # The item element is one of the valid expansion elements for the SGR rule element
6
+ #
7
+ # http://www.w3.org/TR/speech-grammar/#S2.4 --> XML Form
8
+ #
9
+ # The item element has four (optional) attributes: weight, repeat, repeat-prob, and xml:lang (language identifier)
10
+ #
11
+ # http://www.w3.org/TR/speech-grammar/#S2.4.1
12
+ # http://www.w3.org/TR/speech-grammar/#S2.3
13
+ #
14
+ # A weight may be optionally provided for any number of alternatives in an alternative expansion. Weights are simple positive floating point values without exponentials. Legal formats are "n", "n.", ".n" and "n.n" where "n" is a sequence of one or many digits.
15
+ #
16
+ # A weight is nominally a multiplying factor in the likelihood domain of a speech recognition search. A weight of 1.0 is equivalent to providing no weight at all. A weight greater than "1.0" positively biases the alternative and a weight less than "1.0" negatively biases the alternative.
17
+ #
18
+ # repeat has several valid values...
19
+ #
20
+ # Any repeated legal rule expansion is itself a legal rule expansion.
21
+ #
22
+ # Operators are provided that define a legal rule expansion as being another sub-expansion that is optional, that is repeated zero or more times, that is repeated one or more times, or that is repeated some range of times.
23
+ #
24
+ # repeat probability (repeat-prob) indicates the probability of successive repetition of the repeated expansion. It is ignored if repeat is not specified
25
+ #
26
+ # 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
+ #
28
+ class Item < Element
29
+
30
+ register :item
31
+
32
+ VALID_CHILD_TYPES = [Nokogiri::XML::Element, Nokogiri::XML::Text, OneOf, Item, String, Ruleref, Tag, Token].freeze
33
+
34
+ ##
35
+ # Create a new GRXML item element
36
+ #
37
+ # @param [Hash] atts Key-value pairs of options mapping to setter methods
38
+ #
39
+ # @return [Item] an element for use in an GRXML document
40
+ #
41
+ def self.new(atts = {}, &block)
42
+ super 'item', atts, &block
43
+ end
44
+
45
+ ##
46
+ #
47
+ # The optional weight attribute
48
+ #
49
+ # @return [Float]
50
+ #
51
+ def weight
52
+ read_attr :weight, :to_f
53
+ end
54
+
55
+ ##
56
+ #
57
+ # The weight attribute takes a positive (floating point) number
58
+ # NOTE: the standard says a format of "n" is valid (eg. an Integer)
59
+ # TODO: possibly support string and check to see if its a valid digit with regex...
60
+ #
61
+ # @param [Numeric] w
62
+ #
63
+ def weight=(w)
64
+ raise ArgumentError, "A Item's weight attribute must be a positive floating point number" unless w.to_s.match(/[^0-9\.]/) == nil and w.to_f >= 0
65
+ write_attr :weight, w
66
+ end
67
+
68
+ ##
69
+ #
70
+ # The repeat attribute
71
+ #
72
+ # @return [String]
73
+ #
74
+ def repeat
75
+ read_attr :repeat
76
+ end
77
+
78
+ ##
79
+ #
80
+ # TODO: Raise ArgumentError after doing checking. See
81
+ # http://www.w3.org/TR/speech-grammar/#S2.5
82
+ #
83
+ # @param [String] r
84
+ #
85
+ def repeat=(r)
86
+ r = r.to_s
87
+ error = ArgumentError.new "A Item's repeat must be 0 or a positive integer"
88
+
89
+ raise error unless r.match(/[^0-9-]/) == nil and r.scan("-").size <= 1
90
+
91
+ raise error if case di = r.index('-')
92
+ when nil
93
+ r.to_i < 0 # must be 0 or a positive number
94
+ when 0
95
+ true # negative numbers are illegal
96
+ else
97
+ if di == r.length - 1 # repeat 'm' or more times, m must be 0 or a positive number
98
+ r[0, r.length - 1].to_i < 0
99
+ else # verify range m,n is valid
100
+ m, n = r.split('-').map &:to_i
101
+ m < 0 || n < m
102
+ end
103
+ end
104
+ write_attr :repeat, r
105
+ end
106
+
107
+ ##
108
+ #
109
+ # The optional repeat-prob attribute
110
+ #
111
+ # @return [Float]
112
+ #
113
+ def repeat_prob
114
+ read_attr :'repeat-prob', :to_f
115
+ end
116
+
117
+ ##
118
+ # @param [Numeric] ia
119
+ #
120
+ def repeat_prob=(rp)
121
+ raise ArgumentError, "A Item's repeat probablity attribute must be a floating point number between 0.0 and 1.0" unless rp.to_s.match(/[^0-9\.]/) == nil and rp.to_f >= 0 and rp.to_f <= 1.0
122
+ write_attr :'repeat-prob', rp
123
+ end
124
+
125
+ def <<(arg)
126
+ raise InvalidChildError, "A Item can only accept String, Ruleref, Tag or Token as children" unless VALID_CHILD_TYPES.include? arg.class
127
+ super
128
+ end
129
+
130
+ def eql?(o)
131
+ super o, :weight, :repeat, :language
132
+ end
133
+ end # Item
134
+ end # GRXML
135
+ end # RubySpeech
@@ -0,0 +1,42 @@
1
+ module RubySpeech
2
+ module GRXML
3
+ ##
4
+ #
5
+ # The one-of element is one of the valid expansion elements for the SGR rule element
6
+ #
7
+ # http://www.w3.org/TR/speech-grammar/#S2.4 --> XML Form
8
+ #
9
+ # The one-of element has no attributes
10
+ #
11
+ # The one-of element identifies a set of alternative elements. Each alternative expansion is contained in a item element. There must be at least one item element contained within a one-of element.
12
+ #
13
+ # FIXME: Ensure an 'item' element is in the oneof block... this may be at the final draw or when OneOf is called...
14
+ #
15
+ class OneOf < Element
16
+
17
+ register :'one-of'
18
+
19
+ VALID_CHILD_TYPES = [Nokogiri::XML::Element, Nokogiri::XML::Text, Item].freeze
20
+
21
+ ##
22
+ # Create a new GRXML one-of element
23
+ #
24
+ # @param [Hash] atts Key-value pairs of options mapping to setter methods
25
+ #
26
+ # @return [OneOf] an element for use in an GRXML document
27
+ #
28
+ def self.new(atts = {}, &block)
29
+ super 'one-of', atts, &block
30
+ end
31
+
32
+ def <<(arg)
33
+ raise InvalidChildError, "A OneOf can only accept Item as children" unless VALID_CHILD_TYPES.include? arg.class
34
+ super
35
+ end
36
+
37
+ def eql?(o)
38
+ super o, :language
39
+ end
40
+ end # OneOf
41
+ end # GRXML
42
+ end # RubySpeech
@@ -0,0 +1,84 @@
1
+ module RubySpeech
2
+ module GRXML
3
+ ##
4
+ #
5
+ # A rule definition associates a legal rule expansion with a rulename. The rule definition is also responsible for defining the scope of the rule definition: whether it is local to the grammar in which it is defined or whether it may be referenced within other grammars.
6
+ #
7
+ # http://www.w3.org/TR/speech-grammar/#S3
8
+ # http://www.w3.org/TR/speech-grammar/#S3.1
9
+ #
10
+ # The rule element has two attributes: id and scope. The id attribute is always required; the scope is optional.
11
+ #
12
+ # The id must be unique with-in the grammar document
13
+ #
14
+ # The scope is either "private" or "public". If it is not explicitly declared in a rule definition then the scope defaults to "private".
15
+ #
16
+ #
17
+ class Rule < Element
18
+ include XML::Language
19
+
20
+ register :rule
21
+
22
+ VALID_CHILD_TYPES = [Nokogiri::XML::Element, Nokogiri::XML::Text, String, OneOf, Item, Ruleref, Tag, Token].freeze
23
+
24
+ ##
25
+ # Create a new GRXML rule element
26
+ #
27
+ # @param [Hash] atts Key-value pairs of options mapping to setter methods
28
+ #
29
+ # @return [Rule] an element for use in an GRXML document
30
+ #
31
+ def self.new(atts = {}, &block)
32
+ super 'rule', atts, &block
33
+ end
34
+
35
+ ##
36
+ #
37
+ # The id attribute is the unique name to identify the rule
38
+ #
39
+ #
40
+ # @return [String]
41
+ #
42
+ def id
43
+ read_attr :id, :to_sym
44
+ end
45
+
46
+ ##
47
+ # @param [String] ia
48
+ #
49
+ def id=(ia)
50
+ write_attr :id, ia
51
+ end
52
+
53
+ ##
54
+ #
55
+ # The scope attribute is optional...
56
+ #
57
+ # @return [String]
58
+ #
59
+ def scope
60
+ read_attr :scope, :to_sym
61
+ end
62
+
63
+ ##
64
+ #
65
+ # The scope attribute should only be "private" or "public"
66
+ #
67
+ # @param [String] ia
68
+ #
69
+ def scope=(sc)
70
+ raise ArgumentError, "A Rule's scope can only be 'public' or 'private'" unless %w{public private}.include?(sc.to_s)
71
+ write_attr :scope, sc
72
+ end
73
+
74
+ def <<(arg)
75
+ raise InvalidChildError, "A Rule can only accept OneOf, Item, Ruleref, Tag, or Token as children" unless VALID_CHILD_TYPES.include? arg.class
76
+ super
77
+ end
78
+
79
+ def eql?(o)
80
+ super o, :id, :scope, :language
81
+ end
82
+ end # Rule
83
+ end # GRXML
84
+ end # RubySpeech
@@ -0,0 +1,80 @@
1
+ module RubySpeech
2
+ module GRXML
3
+ ##
4
+ #
5
+ # The ruleref element is an empty element which points to another rule expansion in the grammar document.
6
+ #
7
+ # http://www.w3.org/TR/speech-grammar/#S2.2
8
+ #
9
+ # Every rule definition has a local name that must be unique within the scope of the grammar in which it is defined. A rulename must match the "Name" Production of XML 1.0 [XML §2.3] and be a legal XML ID. Section 3.1 documents the rule definition mechanism and the legal naming of rules.
10
+ #
11
+ # The ruleref has three attributes: uri, special and type. There can be one and only one of the uri or special attribute specified on any given ruleref element.
12
+ #
13
+ # The uri attribute contains named identified named rule being referenced
14
+ #
15
+ # optional 'type' attribute specifies the media type for the uri
16
+ #
17
+ class Ruleref < Element
18
+
19
+ register :ruleref
20
+
21
+ ##
22
+ # Create a new GRXML ruleref element
23
+ #
24
+ # @param [Hash] atts Key-value pairs of options mapping to setter methods
25
+ #
26
+ # @return [Ruleref] an element for use in an GRXML document
27
+ #
28
+ def self.new(atts = {}, &block)
29
+ super 'ruleref', atts, &block
30
+ end
31
+
32
+ ##
33
+ # XML URI: in the XML Form of this specification any URI is provided as an attribute to an element; for example the ruleref and lexicon elements.
34
+ #
35
+ # @return [String]
36
+ #
37
+ def uri
38
+ read_attr :uri
39
+ end
40
+
41
+ ##
42
+ # @param [String]
43
+ #
44
+ # @raises ArgumentError if t is nota positive numeric value
45
+ #
46
+ def uri=(u)
47
+ raise ArgumentError, "A Ruleref can only take uri or special" if special
48
+ write_attr :uri, u
49
+ end
50
+
51
+ ##
52
+ # special...
53
+ #
54
+ # @return [String]
55
+ #
56
+ def special
57
+ read_attr :special
58
+ end
59
+
60
+ ##
61
+ # @param [String]
62
+ #
63
+ # TODO: raise ArgumentError if not a valid special...
64
+ #
65
+ def special=(sp)
66
+ raise ArgumentError, "A Ruleref can only take uri or special" if uri
67
+ raise ArgumentError, "The Ruleref#special method only takes :NULL, :VOID, and :GARBAGE" unless %w{NULL VOID GARBAGE}.include? sp.to_s
68
+ write_attr :special, sp
69
+ end
70
+
71
+ def <<(*args)
72
+ raise InvalidChildError, "A Ruleref cannot contain children"
73
+ end
74
+
75
+ def eql?(o)
76
+ super o, :uri, :special
77
+ end
78
+ end # Rule
79
+ end # GRXML
80
+ end # RubySpeech
@@ -0,0 +1,36 @@
1
+ module RubySpeech
2
+ module GRXML
3
+ ##
4
+ #
5
+ # The tag element is one of the valid expansion elements for the SGR rule element
6
+ #
7
+ # http://www.w3.org/TR/speech-grammar/#S2.6
8
+ #
9
+ #
10
+ # TODO: Make sure this is complete...
11
+ #
12
+ #
13
+ class Tag < Element
14
+
15
+ register :tag
16
+
17
+ VALID_CHILD_TYPES = [Nokogiri::XML::Element, Nokogiri::XML::Text, String].freeze
18
+
19
+ ##
20
+ # Create a new GRXML tag element
21
+ #
22
+ # @param [Hash] atts Key-value pairs of options mapping to setter methods
23
+ #
24
+ # @return [Tag] an element for use in an GRXML document
25
+ #
26
+ def self.new(atts = {}, &block)
27
+ super 'tag', atts, &block
28
+ end
29
+
30
+ def <<(arg)
31
+ raise InvalidChildError, "A Tag can only accept Strings as children" unless VALID_CHILD_TYPES.include? arg.class
32
+ super
33
+ end
34
+ end # Tag
35
+ end # GRXML
36
+ end # RubySpeech
@@ -0,0 +1,38 @@
1
+ module RubySpeech
2
+ module GRXML
3
+ ##
4
+ #
5
+ # A token (a.k.a. a terminal symbol) is the part of a grammar that defines words or other entities that may be spoken. Any legal token is a legal expansion.
6
+ #
7
+ # http://www.w3.org/TR/speech-grammar/#S2.1
8
+ #
9
+ # The token element may include an optional xml:lang attribute to indicate the language of the contained token.
10
+ #
11
+ class Token < Element
12
+
13
+ register :token
14
+
15
+ VALID_CHILD_TYPES = [Nokogiri::XML::Element, Nokogiri::XML::Text, String].freeze
16
+
17
+ ##
18
+ # Create a new GRXML token element
19
+ #
20
+ # @param [Hash] atts Key-value pairs of options mapping to setter methods
21
+ #
22
+ # @return [Token] an element for use in an GRXML document
23
+ #
24
+ def self.new(atts = {}, &block)
25
+ super 'token', atts, &block
26
+ end
27
+
28
+ def <<(arg)
29
+ raise InvalidChildError, "A Token can only accept Strings as children" unless VALID_CHILD_TYPES.include? arg.class
30
+ super
31
+ end
32
+
33
+ def eql?(o)
34
+ super o, :language
35
+ end
36
+ end # Token
37
+ end # GRXML
38
+ end # RubySpeech
@@ -0,0 +1,25 @@
1
+ module RubySpeech
2
+ module GRXML
3
+ extend ActiveSupport::Autoload
4
+
5
+ autoload :Element
6
+ autoload :Grammar
7
+ autoload :Rule
8
+ autoload :Item
9
+ autoload :OneOf
10
+ autoload :Ruleref
11
+ autoload :Tag
12
+ autoload :Token
13
+
14
+ InvalidChildError = Class.new StandardError
15
+
16
+ GRXML_NAMESPACE = 'http://www.w3.org/2001/06/grammar'
17
+
18
+ def self.draw(attributes = {}, &block)
19
+ Grammar.new(attributes).tap do |grammar|
20
+ block_return = grammar.instance_eval(&block) if block_given?
21
+ grammar << block_return if block_return.is_a?(String)
22
+ end
23
+ end
24
+ end # GRXML
25
+ end # RubySpeech
@@ -1,11 +1,11 @@
1
- require 'active_support/core_ext/class/inheritable_attributes'
1
+ require 'active_support/core_ext/class/attribute'
2
2
 
3
3
  module RubySpeech
4
4
  module SSML
5
5
  class Element < Niceogiri::XML::Node
6
6
  @@registrations = {}
7
7
 
8
- class_inheritable_accessor :registered_ns, :registered_name
8
+ class_attribute :registered_ns, :registered_name
9
9
 
10
10
  # Register a new stanza class to a name and/or namespace
11
11
  #
@@ -1,3 +1,3 @@
1
1
  module RubySpeech
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/ruby_speech.rb CHANGED
@@ -11,5 +11,6 @@ module RubySpeech
11
11
  autoload :Version
12
12
 
13
13
  autoload :SSML
14
+ autoload :GRXML
14
15
  autoload :XML
15
16
  end