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.
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ pkg/*
5
5
  spec/reports
6
6
  .yardoc
7
7
  doc
8
+ .*.swp
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ # 0.3.0
2
+ * Feature (Taylor Carpenter): Added support for GRXML documents with most elements implemented.
3
+
1
4
  # 0.2.2
2
5
  * Feature: The SSML DSL now supports embedding SSML documents, elements or strings via the `embed` method. This behaves as you might expect:
3
6
 
data/README.md CHANGED
@@ -18,6 +18,7 @@ speak = RubySpeech::SSML.draw do
18
18
  end
19
19
  end
20
20
  end
21
+
21
22
  speak.to_s
22
23
  ```
23
24
 
@@ -44,6 +45,66 @@ Once your `Speak` is fully prepared and you're ready to send it off for processi
44
45
 
45
46
  You may also then need to call `to_s`.
46
47
 
48
+
49
+ Contruct a GRXML (SGR) document like this:
50
+
51
+ ```ruby
52
+ require 'ruby_speech'
53
+
54
+ grammy = RubySpeech::GRXML.draw do
55
+ self.mode = 'dtmf'
56
+ self.root = 'digits'
57
+ rule id: 'digits' do
58
+ one_of do
59
+ 0.upto(9) {|d| item { d.to_s } }
60
+ end
61
+ end
62
+
63
+ rule id: 'pin', scope: 'public' do
64
+ one_of do
65
+ item do
66
+ item repeat: '4' do
67
+ ruleref uri: '#digit'
68
+ end
69
+ "#"
70
+ end
71
+ item do
72
+ "* 9"
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ grammy.to_s
79
+ ```
80
+
81
+ which becomes
82
+
83
+ ```xml
84
+ <grammar xmlns="http://www.w3.org/2001/06/grammar" version="1.0" xml:lang="en-US" mode="dtmf" root="digits">
85
+ <rule id="digits">
86
+ <one-of>
87
+ <item>0</item>
88
+ <item>1</item>
89
+ <item>2</item>
90
+ <item>3</item>
91
+ <item>4</item>
92
+ <item>5</item>
93
+ <item>6</item>
94
+ <item>7</item>
95
+ <item>8</item>
96
+ <item>9</item>
97
+ </one-of>
98
+ </rule>
99
+ <rule id="pin" scope="public">
100
+ <one-of>
101
+ <item><item repeat="4"><ruleref uri="#digit"/></item>#</item>
102
+ <item>* 9</item>
103
+ </one-of>
104
+ </rule>
105
+ </grammar>
106
+ ```
107
+
47
108
  Check out the [YARD documentation](http://rdoc.info/github/benlangfeld/ruby_speech/master/frames) for more
48
109
 
49
110
  ## Features:
@@ -56,6 +117,15 @@ Check out the [YARD documentation](http://rdoc.info/github/benlangfeld/ruby_spee
56
117
  * `<break/>`
57
118
  * `<audio/>`
58
119
 
120
+ ### GRXML
121
+ * Document construction
122
+ * `<item/>`
123
+ * `<one-of/>`
124
+ * `<rule/>`
125
+ * `<ruleref/>`
126
+ * `<tag/>`
127
+ * `<token/>`
128
+
59
129
  ## TODO:
60
130
  ### SSML
61
131
  #### Document Structure
@@ -69,6 +139,11 @@ Check out the [YARD documentation](http://rdoc.info/github/benlangfeld/ruby_spee
69
139
  * `<mark/>`
70
140
  * `<desc/>`
71
141
 
142
+ ### GRXML
143
+ * `<meta/>` and `<metadata/>`
144
+ * `<example/>`
145
+ * `<lexicon/>`
146
+
72
147
 
73
148
  ## Links:
74
149
  * [Source](https://github.com/benlangfeld/ruby_speech)
@@ -0,0 +1,317 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
3
+ <xsd:annotation>
4
+ <xsd:documentation>SRGS 1.0 Core Schema (20031204)</xsd:documentation>
5
+ </xsd:annotation>
6
+ <xsd:annotation>
7
+ <xsd:documentation>
8
+ Copyright 1998-2003 W3C (MIT, ERCIM, Keio),
9
+ All Rights Reserved. Permission to use, copy, modify and
10
+ distribute the SRGS core schema and its accompanying documentation
11
+ for any purpose and without fee is hereby granted in
12
+ perpetuity, provided that the above copyright notice and this
13
+ paragraph appear in all copies. The copyright holders make no
14
+ representation about the suitability of the schema for any purpose.
15
+ It is provided "as is" without expressed or implied warranty.
16
+ </xsd:documentation>
17
+ </xsd:annotation>
18
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace"
19
+ schemaLocation="xml.xsd"/>
20
+ <!--<xsd:import namespace="http://www.w3.org/XML/1998/namespace"
21
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>-->
22
+ <xsd:annotation>
23
+ <xsd:documentation>General Datatypes</xsd:documentation>
24
+ </xsd:annotation>
25
+ <xsd:annotation>
26
+ <xsd:documentation>Grammar-specific datatypes</xsd:documentation>
27
+ </xsd:annotation>
28
+ <xsd:simpleType name="tag">
29
+ <xsd:restriction base="xsd:string"/>
30
+ </xsd:simpleType>
31
+ <xsd:simpleType name="example">
32
+ <xsd:restriction base="xsd:string"/>
33
+ </xsd:simpleType>
34
+ <xsd:simpleType name="Id.datatype">
35
+ <xsd:annotation>
36
+ <xsd:documentation>
37
+ does not expression the constraint that NULL VOID GARBAGE are illegal as rule name
38
+ </xsd:documentation>
39
+ </xsd:annotation>
40
+ <xsd:restriction base="xsd:ID">
41
+ <xsd:pattern value="[^.:\-]+"/>
42
+ </xsd:restriction>
43
+ </xsd:simpleType>
44
+ <xsd:simpleType name="Scope.datatype">
45
+ <xsd:restriction base="xsd:NMTOKEN">
46
+ <xsd:enumeration value="private"/>
47
+ <xsd:enumeration value="public"/>
48
+ </xsd:restriction>
49
+ </xsd:simpleType>
50
+ <xsd:simpleType name="Special.datatype">
51
+ <xsd:restriction base="xsd:NMTOKEN">
52
+ <xsd:enumeration value="NULL"/>
53
+ <xsd:enumeration value="VOID"/>
54
+ <xsd:enumeration value="GARBAGE"/>
55
+ </xsd:restriction>
56
+ </xsd:simpleType>
57
+ <xsd:simpleType name="Repeat-prob.datatype">
58
+ <xsd:restriction base="xsd:decimal">
59
+ <xsd:minInclusive value="0.0"/>
60
+ <xsd:maxInclusive value="1.0"/>
61
+ </xsd:restriction>
62
+ </xsd:simpleType>
63
+ <xsd:simpleType name="Repeat.datatype">
64
+ <xsd:annotation>
65
+ <xsd:documentation>
66
+ does not expression the constraint in n-m that m must be greater than n
67
+ </xsd:documentation>
68
+ </xsd:annotation>
69
+ <xsd:restriction base="xsd:string">
70
+ <xsd:pattern value="[0-9]+"/>
71
+ <xsd:pattern value="[0-9]+-([0-9]+)?"/>
72
+ <xsd:pattern value="([0-9]+)?-[0-9]+"/>
73
+ </xsd:restriction>
74
+ </xsd:simpleType>
75
+ <xsd:simpleType name="Weight.datatype">
76
+ <xsd:restriction base="xsd:string">
77
+ <xsd:pattern value="[0-9]+[.]?"/>
78
+ <xsd:pattern value="([0-9]+)?[.][0-9]+"/>
79
+ </xsd:restriction>
80
+ </xsd:simpleType>
81
+ <xsd:simpleType name="Tag-format.datatype">
82
+ <xsd:restriction base="xsd:anyURI"/>
83
+ </xsd:simpleType>
84
+ <xsd:simpleType name="Version.datatype">
85
+ <xsd:restriction base="xsd:NMTOKEN"/>
86
+ </xsd:simpleType>
87
+ <xsd:simpleType name="Root.datatype">
88
+ <xsd:annotation>
89
+ <xsd:documentation>does not expression the constraint that NULL VOID GARBAGE
90
+ are illegal as rule name</xsd:documentation>
91
+ </xsd:annotation>
92
+ <xsd:restriction base="xsd:IDREF">
93
+ <xsd:pattern value="[^.:\-]+"/>
94
+ </xsd:restriction>
95
+ </xsd:simpleType>
96
+ <xsd:simpleType name="Mode.datatype">
97
+ <xsd:restriction base="xsd:NMTOKEN">
98
+ <xsd:enumeration value="voice"/>
99
+ <xsd:enumeration value="dtmf"/>
100
+ </xsd:restriction>
101
+ </xsd:simpleType>
102
+ <xsd:simpleType name="Type.datatype">
103
+ <xsd:restriction base="xsd:string"/>
104
+ </xsd:simpleType>
105
+ <xsd:annotation>
106
+ <xsd:documentation>Grammar Attributes</xsd:documentation>
107
+ </xsd:annotation>
108
+ <xsd:attributeGroup name="Tag-format.attrib">
109
+ <xsd:annotation>
110
+ <xsd:documentation/>
111
+ </xsd:annotation>
112
+ <xsd:attribute name="tag-format" type="Tag-format.datatype"/>
113
+ </xsd:attributeGroup>
114
+ <xsd:attributeGroup name="Version.attrib">
115
+ <xsd:annotation>
116
+ <xsd:documentation/>
117
+ </xsd:annotation>
118
+ <xsd:attribute name="version" type="Version.datatype"/>
119
+ </xsd:attributeGroup>
120
+ <xsd:attributeGroup name="Mode.attrib">
121
+ <xsd:annotation>
122
+ <xsd:documentation/>
123
+ </xsd:annotation>
124
+ <xsd:attribute name="mode" type="Mode.datatype" default="voice"/>
125
+ </xsd:attributeGroup>
126
+ <xsd:attributeGroup name="Root.attrib">
127
+ <xsd:annotation>
128
+ <xsd:documentation/>
129
+ </xsd:annotation>
130
+ <xsd:attribute name="root" type="Root.datatype"/>
131
+ </xsd:attributeGroup>
132
+ <xsd:attributeGroup name="Special.attrib">
133
+ <xsd:annotation>
134
+ <xsd:documentation/>
135
+ </xsd:annotation>
136
+ <xsd:attribute name="special" type="Special.datatype"/>
137
+ </xsd:attributeGroup>
138
+ <xsd:attributeGroup name="Repeat-prob.attrib">
139
+ <xsd:annotation>
140
+ <xsd:documentation/>
141
+ </xsd:annotation>
142
+ <xsd:attribute name="repeat-prob" type="Repeat-prob.datatype"/>
143
+ </xsd:attributeGroup>
144
+ <xsd:attributeGroup name="Repeat.attrib">
145
+ <xsd:annotation>
146
+ <xsd:documentation/>
147
+ </xsd:annotation>
148
+ <xsd:attribute name="repeat" type="Repeat.datatype"/>
149
+ </xsd:attributeGroup>
150
+ <xsd:attributeGroup name="Type.attrib">
151
+ <xsd:annotation>
152
+ <xsd:documentation/>
153
+ </xsd:annotation>
154
+ <xsd:attribute name="type" type="Type.datatype"/>
155
+ </xsd:attributeGroup>
156
+ <xsd:attributeGroup name="Weight.attrib">
157
+ <xsd:annotation>
158
+ <xsd:documentation/>
159
+ </xsd:annotation>
160
+ <xsd:attribute name="weight" type="Weight.datatype"/>
161
+ </xsd:attributeGroup>
162
+ <xsd:attributeGroup name="Id.attrib">
163
+ <xsd:annotation>
164
+ <xsd:documentation/>
165
+ </xsd:annotation>
166
+ <xsd:attribute name="id" type="Id.datatype" use="required"/>
167
+ </xsd:attributeGroup>
168
+ <xsd:attributeGroup name="Scope.attrib">
169
+ <xsd:annotation>
170
+ <xsd:documentation/>
171
+ </xsd:annotation>
172
+ <xsd:attribute name="scope" type="Scope.datatype" default="private"/>
173
+ </xsd:attributeGroup>
174
+ <xsd:attributeGroup name="Token.attribs">
175
+ <xsd:annotation>
176
+ <xsd:documentation/>
177
+ </xsd:annotation>
178
+ <xsd:attribute ref="xml:lang"/>
179
+ </xsd:attributeGroup>
180
+ <xsd:attributeGroup name="One-of.attribs">
181
+ <xsd:annotation>
182
+ <xsd:documentation/>
183
+ </xsd:annotation>
184
+ <xsd:attribute ref="xml:lang"/>
185
+ </xsd:attributeGroup>
186
+ <xsd:attributeGroup name="Item.attribs">
187
+ <xsd:annotation>
188
+ <xsd:documentation/>
189
+ </xsd:annotation>
190
+ <xsd:attributeGroup ref="Repeat-prob.attrib"/>
191
+ <xsd:attributeGroup ref="Repeat.attrib"/>
192
+ <xsd:attributeGroup ref="Weight.attrib"/>
193
+ <xsd:attribute ref="xml:lang"/>
194
+ </xsd:attributeGroup>
195
+ <xsd:attributeGroup name="Grammar.attribs">
196
+ <xsd:annotation>
197
+ <xsd:documentation/>
198
+ </xsd:annotation>
199
+ <xsd:attributeGroup ref="Tag-format.attrib"/>
200
+ <xsd:attributeGroup ref="Version.attrib"/>
201
+ <xsd:attribute ref="xml:lang"/>
202
+ <xsd:attribute ref="xml:base"/>
203
+ <xsd:attributeGroup ref="Root.attrib"/>
204
+ <xsd:attributeGroup ref="Mode.attrib"/>
205
+ </xsd:attributeGroup>
206
+ <xsd:attributeGroup name="Ruleref.attribs">
207
+ <xsd:annotation>
208
+ <xsd:documentation/>
209
+ </xsd:annotation>
210
+ <xsd:attributeGroup ref="Type.attrib"/>
211
+ <xsd:attribute name="uri" type="xsd:anyURI"/>
212
+ <xsd:attributeGroup ref="Special.attrib"/>
213
+ </xsd:attributeGroup>
214
+ <xsd:attributeGroup name="Rule.attribs">
215
+ <xsd:annotation>
216
+ <xsd:documentation/>
217
+ </xsd:annotation>
218
+ <xsd:attributeGroup ref="Id.attrib"/>
219
+ <xsd:attributeGroup ref="Scope.attrib"/>
220
+ </xsd:attributeGroup>
221
+ <xsd:attributeGroup name="Lexicon.attribs">
222
+ <xsd:annotation>
223
+ <xsd:documentation/>
224
+ </xsd:annotation>
225
+ <xsd:attribute name="uri" type="xsd:anyURI" use="required"/>
226
+ <xsd:attributeGroup ref="Type.attrib"/>
227
+ </xsd:attributeGroup>
228
+ <xsd:attributeGroup name="Meta.attribs">
229
+ <xsd:annotation>
230
+ <xsd:documentation/>
231
+ </xsd:annotation>
232
+ <xsd:attribute name="name" type="xsd:NMTOKEN"/>
233
+ <xsd:attribute name="content" type="xsd:string" use="required"/>
234
+ <xsd:attribute name="http-equiv" type="xsd:NMTOKEN"/>
235
+ </xsd:attributeGroup>
236
+ <xsd:annotation>
237
+ <xsd:documentation>Content Models</xsd:documentation>
238
+ </xsd:annotation>
239
+ <xsd:group name="rule-expansion">
240
+ <xsd:choice>
241
+ <xsd:element name="token" type="token"/>
242
+ <xsd:element name="ruleref" type="ruleref"/>
243
+ <xsd:element name="item" type="item"/>
244
+ <xsd:element name="one-of" type="one-of"/>
245
+ <xsd:element name="tag" type="tag"/>
246
+ </xsd:choice>
247
+ </xsd:group>
248
+ <xsd:complexType name="ruleref">
249
+ <xsd:attributeGroup ref="Ruleref.attribs"/>
250
+ </xsd:complexType>
251
+ <xsd:complexType name="token" mixed="true">
252
+ <xsd:annotation>
253
+ <xsd:documentation>does not expression the constraint that empty content is illegal
254
+ </xsd:documentation>
255
+ </xsd:annotation>
256
+ <xsd:attributeGroup ref="Token.attribs"/>
257
+ </xsd:complexType>
258
+ <xsd:complexType name="one-of">
259
+ <xsd:sequence maxOccurs="unbounded">
260
+ <xsd:element name="item" type="item"/>
261
+ </xsd:sequence>
262
+ <xsd:attributeGroup ref="One-of.attribs"/>
263
+ </xsd:complexType>
264
+ <xsd:complexType name="item" mixed="true">
265
+ <xsd:group ref="rule-expansion" minOccurs="0" maxOccurs="unbounded"/>
266
+ <xsd:attributeGroup ref="Item.attribs"/>
267
+ </xsd:complexType>
268
+ <xsd:complexType name="rule" mixed="true">
269
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
270
+ <xsd:group ref="rule-expansion"/>
271
+ <xsd:element name="example" type="example"/>
272
+ </xsd:choice>
273
+ <xsd:attributeGroup ref="Rule.attribs"/>
274
+ </xsd:complexType>
275
+ <xsd:complexType name="lexicon">
276
+ <xsd:attributeGroup ref="Lexicon.attribs"/>
277
+ </xsd:complexType>
278
+ <xsd:complexType name="meta">
279
+ <xsd:attributeGroup ref="Meta.attribs"/>
280
+ </xsd:complexType>
281
+ <xsd:complexType name="metadata">
282
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
283
+ <xsd:any namespace="##other" processContents="lax"/>
284
+ </xsd:choice>
285
+ <xsd:anyAttribute namespace="##any" processContents="strict"/>
286
+ </xsd:complexType>
287
+
288
+ <xsd:group name="grammar.class">
289
+ <xsd:annotation>
290
+ <xsd:documentation>grammar content model</xsd:documentation>
291
+ </xsd:annotation>
292
+ <xsd:sequence>
293
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
294
+ <xsd:element name="lexicon" type="lexicon"/>
295
+ <xsd:element name="meta" type="meta"/>
296
+ <xsd:element name="metadata" type="metadata"/>
297
+ <xsd:element name="tag" type="tag"/>
298
+ </xsd:choice>
299
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
300
+ <xsd:element name="rule" type="rule"/>
301
+ </xsd:choice>
302
+ </xsd:sequence>
303
+ </xsd:group>
304
+
305
+ <xsd:complexType name="grammar">
306
+ <xsd:annotation>
307
+ <xsd:documentation>grammar type with grammar content model and attributes</xsd:documentation>
308
+ </xsd:annotation>
309
+ <xsd:group ref="grammar.class"/>
310
+ <xsd:attributeGroup ref="Grammar.attribs"/>
311
+ </xsd:complexType>
312
+
313
+ <xsd:annotation>
314
+ <xsd:documentation>Global Elements</xsd:documentation>
315
+ </xsd:annotation>
316
+ <xsd:element name="grammar" type="grammar"/>
317
+ </xsd:schema>
@@ -0,0 +1,37 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <xsd:schema targetNamespace="http://www.w3.org/2001/06/grammar"
4
+ xmlns="http://www.w3.org/2001/06/grammar"
5
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
6
+ elementFormDefault="qualified">
7
+ <xsd:annotation>
8
+ <xsd:documentation>SRGS 1.0 Schema (20031204)</xsd:documentation>
9
+ </xsd:annotation>
10
+ <xsd:annotation>
11
+ <xsd:documentation>Copyright 1998-2003 W3C (MIT, ERCIM, Keio),
12
+ All Rights Reserved. Permission to use, copy, modify and
13
+ distribute the SRGS schema and its accompanying documentation
14
+ for any purpose and without fee is hereby granted in
15
+ perpetuity, provided that the above copyright notice and this
16
+ paragraph appear in all copies. The copyright holders make no
17
+ representation about the suitability of the schema for any purpose.
18
+ It is provided "as is" without expressed or implied warranty.
19
+ </xsd:documentation>
20
+ </xsd:annotation>
21
+
22
+ <xsd:redefine schemaLocation="grammar-core.xsd">
23
+ <xsd:annotation>
24
+ <xsd:documentation>restricted grammar type so that version attribute is mandatory</xsd:documentation>
25
+ </xsd:annotation>
26
+ <xsd:complexType name="grammar">
27
+ <xsd:complexContent>
28
+ <xsd:restriction base="grammar">
29
+ <xsd:group ref="grammar.class"/>
30
+ <xsd:attribute name="version" type="Version.datatype" use="required"/>
31
+ </xsd:restriction>
32
+ </xsd:complexContent>
33
+ </xsd:complexType>
34
+ </xsd:redefine>
35
+
36
+
37
+ </xsd:schema>
@@ -20,7 +20,10 @@ It is provided "as is" without expressed or implied warranty.
20
20
  <xsd:documentation>Importing dependent namespaces</xsd:documentation>
21
21
  </xsd:annotation>
22
22
  <xsd:import namespace="http://www.w3.org/XML/1998/namespace"
23
- schemaLocation="http://www.w3.org/2001/xml.xsd"/>
23
+ schemaLocation="xml.xsd"/>
24
+
25
+ <!--<xsd:import namespace="http://www.w3.org/XML/1998/namespace"
26
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>-->
24
27
  <xsd:annotation>
25
28
  <xsd:documentation>General Datatypes</xsd:documentation>
26
29
  </xsd:annotation>
@@ -0,0 +1,107 @@
1
+ require 'active_support/core_ext/class/attribute'
2
+
3
+ module RubySpeech
4
+ module GRXML
5
+ class Element < Niceogiri::XML::Node
6
+ @@registrations = {}
7
+
8
+ class_attribute :registered_ns, :registered_name
9
+
10
+ # Register a new stanza class to a name and/or namespace
11
+ #
12
+ # This registers a namespace that is used when looking
13
+ # up the class name of the object to instantiate when a new
14
+ # stanza is received
15
+ #
16
+ # @param [#to_s] name the name of the node
17
+ #
18
+ def self.register(name)
19
+ self.registered_name = name.to_s
20
+ self.registered_ns = GRXML_NAMESPACE
21
+ @@registrations[[self.registered_name, self.registered_ns]] = self
22
+ end
23
+
24
+ # Find the class to use given the name and namespace of a stanza
25
+ #
26
+ # @param [#to_s] name the name to lookup
27
+ #
28
+ # @return [Class, nil] the class appropriate for the name
29
+ def self.class_from_registration(name)
30
+ @@registrations[[name.to_s, GRXML_NAMESPACE]]
31
+ end
32
+
33
+ # Import an XML::Node to the appropriate class
34
+ #
35
+ # Looks up the class the node should be then creates it based on the
36
+ # elements of the XML::Node
37
+ # @param [XML::Node] node the node to import
38
+ # @return the appropriate object based on the node name and namespace
39
+ def self.import(node)
40
+ return node.content if node.is_a?(Nokogiri::XML::Text)
41
+ klass = class_from_registration(node.element_name)
42
+ if klass && klass != self
43
+ klass.import node
44
+ else
45
+ new.inherit node
46
+ end
47
+ end
48
+
49
+ # Inherit the attributes and children of an XML::Node
50
+ #
51
+ # @param [XML::Node] node the node to inherit
52
+ # @return [self]
53
+ def inherit(node)
54
+ inherit_attrs node.attributes
55
+ node.children.each do |c|
56
+ self << c.dup
57
+ end
58
+ self
59
+ end
60
+
61
+ def self.new(element_name, atts = {}, &block)
62
+ super(element_name) do |new_node|
63
+ atts.each_pair { |k, v| new_node.send :"#{k}=", v }
64
+ block_return = new_node.instance_eval &block if block_given?
65
+ new_node << new_node.encode_special_chars(block_return) if block_return.is_a?(String)
66
+ end
67
+ end
68
+
69
+ def children
70
+ super.map { |c| Element.import c }
71
+ end
72
+
73
+ def embed(other)
74
+ case other
75
+ when String
76
+ self << encode_special_chars(other)
77
+ when Grammar
78
+ other.children.each do |child|
79
+ self << child
80
+ end
81
+ when Element
82
+ self << other
83
+ else
84
+ raise ArgumentError, "Can only embed a String or an GRXML element"
85
+ end
86
+ end
87
+
88
+ def method_missing(method_name, *args, &block)
89
+ const_name = method_name.to_s.sub('ssml', '').titleize.gsub(' ', '')
90
+ const = GRXML.const_get const_name
91
+ if const && self.class::VALID_CHILD_TYPES.include?(const)
92
+ if const == String
93
+ self << encode_special_chars(args.first)
94
+ else
95
+ self << const.new(*args, &block)
96
+ end
97
+ else
98
+ super
99
+ end
100
+ end
101
+
102
+ def eql?(o, *args)
103
+ super o, :content, :children, *args
104
+ end
105
+ end # Element
106
+ end # GRXML
107
+ end # RubySpeech