OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview An interface definition of a speech rule. | 6 * @fileoverview An interface definition of a speech rule. |
7 * | 7 * |
8 * A speech rule is a data structure along with supporting methods that | 8 * A speech rule is a data structure along with supporting methods that |
9 * stipulates how to transform a tree structure such as XML, a browser DOM, or | 9 * stipulates how to transform a tree structure such as XML, a browser DOM, or |
10 * HTML into a format (usually strings) suitable for rendering by a | 10 * HTML into a format (usually strings) suitable for rendering by a |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 /** | 47 /** |
48 * | 48 * |
49 * @override | 49 * @override |
50 */ | 50 */ |
51 cvox.SpeechRule.prototype.toString = function() { | 51 cvox.SpeechRule.prototype.toString = function() { |
52 var cstrStrings = []; | 52 var cstrStrings = []; |
53 for (var key in this.dynamicCstr) { | 53 for (var key in this.dynamicCstr) { |
54 cstrStrings.push(this.dynamicCstr[key]); | 54 cstrStrings.push(this.dynamicCstr[key]); |
55 } | 55 } |
56 return this.name + ' | ' + cstrStrings.join('.') + ' | ' + | 56 return this.name + ' | ' + cstrStrings.join('.') + ' | ' + |
57 this.precondition.toString() + ' ==> ' + | 57 this.precondition.toString() + ' ==> ' + this.action.toString(); |
58 this.action.toString(); | |
59 }; | 58 }; |
60 | 59 |
61 | 60 |
62 /** | 61 /** |
63 * Mapping for types of speech rule components. | 62 * Mapping for types of speech rule components. |
64 * @enum {string} | 63 * @enum {string} |
65 */ | 64 */ |
66 cvox.SpeechRule.Type = { | 65 cvox.SpeechRule.Type = { |
67 NODE: 'NODE', | 66 NODE: 'NODE', |
68 MULTI: 'MULTI', | 67 MULTI: 'MULTI', |
69 TEXT: 'TEXT', | 68 TEXT: 'TEXT', |
70 PERSONALITY: 'PERSONALITY' | 69 PERSONALITY: 'PERSONALITY' |
71 }; | 70 }; |
72 | 71 |
73 | 72 |
74 /** | 73 /** |
75 * Maps a string to a valid speech rule type. | 74 * Maps a string to a valid speech rule type. |
76 * @param {string} str Input string. | 75 * @param {string} str Input string. |
77 * @return {cvox.SpeechRule.Type} | 76 * @return {cvox.SpeechRule.Type} |
78 */ | 77 */ |
79 cvox.SpeechRule.Type.fromString = function(str) { | 78 cvox.SpeechRule.Type.fromString = function(str) { |
80 switch (str) { | 79 switch (str) { |
81 case '[n]': return cvox.SpeechRule.Type.NODE; | 80 case '[n]': |
82 case '[m]': return cvox.SpeechRule.Type.MULTI; | 81 return cvox.SpeechRule.Type.NODE; |
83 case '[t]': return cvox.SpeechRule.Type.TEXT; | 82 case '[m]': |
84 case '[p]': return cvox.SpeechRule.Type.PERSONALITY; | 83 return cvox.SpeechRule.Type.MULTI; |
85 default: throw 'Parse error: ' + str; | 84 case '[t]': |
| 85 return cvox.SpeechRule.Type.TEXT; |
| 86 case '[p]': |
| 87 return cvox.SpeechRule.Type.PERSONALITY; |
| 88 default: |
| 89 throw 'Parse error: ' + str; |
86 } | 90 } |
87 }; | 91 }; |
88 | 92 |
89 | 93 |
90 /** | 94 /** |
91 * Maps a speech rule type to a human-readable string. | 95 * Maps a speech rule type to a human-readable string. |
92 * @param {cvox.SpeechRule.Type} speechType | 96 * @param {cvox.SpeechRule.Type} speechType |
93 * @return {string} Output string. | 97 * @return {string} Output string. |
94 */ | 98 */ |
95 cvox.SpeechRule.Type.toString = function(speechType) { | 99 cvox.SpeechRule.Type.toString = function(speechType) { |
96 switch (speechType) { | 100 switch (speechType) { |
97 case cvox.SpeechRule.Type.NODE: return '[n]'; | 101 case cvox.SpeechRule.Type.NODE: |
98 case cvox.SpeechRule.Type.MULTI: return '[m]'; | 102 return '[n]'; |
99 case cvox.SpeechRule.Type.TEXT: return '[t]'; | 103 case cvox.SpeechRule.Type.MULTI: |
100 case cvox.SpeechRule.Type.PERSONALITY: return '[p]'; | 104 return '[m]'; |
101 default: throw 'Unknown type error: ' + speechType; | 105 case cvox.SpeechRule.Type.TEXT: |
| 106 return '[t]'; |
| 107 case cvox.SpeechRule.Type.PERSONALITY: |
| 108 return '[p]'; |
| 109 default: |
| 110 throw 'Unknown type error: ' + speechType; |
102 } | 111 } |
103 }; | 112 }; |
104 | 113 |
105 | 114 |
106 /** | 115 /** |
107 * Defines a component within a speech rule. | 116 * Defines a component within a speech rule. |
108 * @param {{type: cvox.SpeechRule.Type, content: string}} kwargs The input | 117 * @param {{type: cvox.SpeechRule.Type, content: string}} kwargs The input |
109 * component in JSON format. | 118 * component in JSON format. |
110 * @constructor | 119 * @constructor |
111 */ | 120 */ |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 case cvox.SpeechRule.Type.NODE: | 165 case cvox.SpeechRule.Type.NODE: |
157 case cvox.SpeechRule.Type.MULTI: | 166 case cvox.SpeechRule.Type.MULTI: |
158 var bracket = rest.indexOf(' ('); | 167 var bracket = rest.indexOf(' ('); |
159 if (bracket == -1) { | 168 if (bracket == -1) { |
160 output.content = rest.trim(); | 169 output.content = rest.trim(); |
161 rest = ''; | 170 rest = ''; |
162 break; | 171 break; |
163 } | 172 } |
164 output.content = rest.substring(0, bracket).trim(); | 173 output.content = rest.substring(0, bracket).trim(); |
165 rest = rest.slice(bracket).trimLeft(); | 174 rest = rest.slice(bracket).trimLeft(); |
166 break; | 175 break; |
167 } | 176 } |
168 output = new cvox.SpeechRule.Component(output); | 177 output = new cvox.SpeechRule.Component(output); |
169 if (rest) { | 178 if (rest) { |
170 output.addAttributes(rest); | 179 output.addAttributes(rest); |
171 } | 180 } |
172 return output; | 181 return output; |
173 }; | 182 }; |
174 | 183 |
175 | 184 |
176 /** | 185 /** |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 }; | 253 }; |
245 | 254 |
246 | 255 |
247 /** | 256 /** |
248 * Parses an input string into a speech rule class object. | 257 * Parses an input string into a speech rule class object. |
249 * @param {string} input The input string. | 258 * @param {string} input The input string. |
250 * @return {cvox.SpeechRule.Action} The resulting object. | 259 * @return {cvox.SpeechRule.Action} The resulting object. |
251 */ | 260 */ |
252 cvox.SpeechRule.Action.fromString = function(input) { | 261 cvox.SpeechRule.Action.fromString = function(input) { |
253 var comps = cvox.SpeechRule.splitString_(input, ';') | 262 var comps = cvox.SpeechRule.splitString_(input, ';') |
254 .filter(function(x) {return x.match(/\S/);}) | 263 .filter(function(x) { |
255 .map(function(x) {return x.trim();}); | 264 return x.match(/\S/); |
| 265 }) |
| 266 .map(function(x) { |
| 267 return x.trim(); |
| 268 }); |
256 var newComps = []; | 269 var newComps = []; |
257 for (var i = 0; i < comps.length; i++) { | 270 for (var i = 0; i < comps.length; i++) { |
258 var comp = cvox.SpeechRule.Component.fromString(comps[i]); | 271 var comp = cvox.SpeechRule.Component.fromString(comps[i]); |
259 if (comp) { | 272 if (comp) { |
260 newComps.push(comp); | 273 newComps.push(comp); |
261 } | 274 } |
262 } | 275 } |
263 return new cvox.SpeechRule.Action(newComps); | 276 return new cvox.SpeechRule.Action(newComps); |
264 }; | 277 }; |
265 | 278 |
266 | 279 |
267 /** | 280 /** |
268 * @override | 281 * @override |
269 */ | 282 */ |
270 cvox.SpeechRule.Action.prototype.toString = function() { | 283 cvox.SpeechRule.Action.prototype.toString = function() { |
271 var comps = this.components.map(function(c) { return c.toString(); }); | 284 var comps = this.components.map(function(c) { |
| 285 return c.toString(); |
| 286 }); |
272 return comps.join('; '); | 287 return comps.join('; '); |
273 }; | 288 }; |
274 | 289 |
275 | 290 |
276 // TODO (sorge) Separatation of xpath expressions and custom functions. | 291 // TODO (sorge) Separatation of xpath expressions and custom functions. |
277 // Also test validity of xpath expressions. | 292 // Also test validity of xpath expressions. |
278 /** | 293 /** |
279 * Constructs a valid precondition for a speech rule. | 294 * Constructs a valid precondition for a speech rule. |
280 * @param {string} query A node selector function or xpath expression. | 295 * @param {string} query A node selector function or xpath expression. |
281 * @param {Array<string>=} opt_constraints A list of constraint functions. | 296 * @param {Array<string>=} opt_constraints A list of constraint functions. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 while (str != '') { | 331 while (str != '') { |
317 var sepPos = str.search(sep); | 332 var sepPos = str.search(sep); |
318 if (sepPos == -1) { | 333 if (sepPos == -1) { |
319 if ((str.match(/"/g) || []).length % 2 != 0) { | 334 if ((str.match(/"/g) || []).length % 2 != 0) { |
320 throw new cvox.SpeechRule.OutputError( | 335 throw new cvox.SpeechRule.OutputError( |
321 'Invalid string in expression: ' + str); | 336 'Invalid string in expression: ' + str); |
322 } | 337 } |
323 strList.push(prefix + str); | 338 strList.push(prefix + str); |
324 prefix = ''; | 339 prefix = ''; |
325 str = ''; | 340 str = ''; |
326 } else if ( | 341 } else if ((str.substring(0, sepPos).match(/"/g) || []).length % 2 == 0) { |
327 (str.substring(0, sepPos).match(/"/g) || []).length % 2 == 0) { | |
328 strList.push(prefix + str.substring(0, sepPos)); | 342 strList.push(prefix + str.substring(0, sepPos)); |
329 prefix = ''; | 343 prefix = ''; |
330 str = str.substring(sepPos + 1); | 344 str = str.substring(sepPos + 1); |
331 } else { | 345 } else { |
332 var nextQuot = str.substring(sepPos).search('"'); | 346 var nextQuot = str.substring(sepPos).search('"'); |
333 if (nextQuot == -1) { | 347 if (nextQuot == -1) { |
334 throw new cvox.SpeechRule.OutputError( | 348 throw new cvox.SpeechRule.OutputError( |
335 'Invalid string in expression: ' + str); | 349 'Invalid string in expression: ' + str); |
336 } else { | 350 } else { |
337 prefix = prefix + str.substring(0, sepPos + nextQuot + 1); | 351 prefix = prefix + str.substring(0, sepPos + nextQuot + 1); |
338 str = str.substring(sepPos + nextQuot + 1); | 352 str = str.substring(sepPos + nextQuot + 1); |
339 } | 353 } |
340 } | 354 } |
341 } | 355 } |
342 if (prefix) { | 356 if (prefix) { |
343 strList.push(prefix); | 357 strList.push(prefix); |
344 } | 358 } |
345 return strList; | 359 return strList; |
346 }; | 360 }; |
347 | 361 |
348 | 362 |
349 /** | 363 /** |
350 * Attributes for dynamic constraints. | 364 * Attributes for dynamic constraints. |
351 * We define one default attribute as style. Speech rule stores can add other | 365 * We define one default attribute as style. Speech rule stores can add other |
352 * attributes later. | 366 * attributes later. |
353 * @enum {string} | 367 * @enum {string} |
354 */ | 368 */ |
355 cvox.SpeechRule.DynamicCstrAttrib = | 369 cvox.SpeechRule.DynamicCstrAttrib = { |
356 { | |
357 STYLE: 'style' | 370 STYLE: 'style' |
358 }; | 371 }; |
359 | 372 |
360 | 373 |
361 /** | 374 /** |
362 * Dynamic constraints are a means to specialize rules that can be changed | 375 * Dynamic constraints are a means to specialize rules that can be changed |
363 * dynamically by the user, for example by choosing different styles, etc. | 376 * dynamically by the user, for example by choosing different styles, etc. |
364 * @typedef {!Object<cvox.SpeechRule.DynamicCstrAttrib, string>} | 377 * @typedef {!Object<cvox.SpeechRule.DynamicCstrAttrib, string>} |
365 */ | 378 */ |
366 cvox.SpeechRule.DynamicCstr; | 379 cvox.SpeechRule.DynamicCstr; |
367 | 380 |
368 | 381 |
369 /** | 382 /** |
370 * Error object for signaling parsing errors. | 383 * Error object for signaling parsing errors. |
371 * @param {string} msg The error message. | 384 * @param {string} msg The error message. |
372 * @constructor | 385 * @constructor |
373 * @extends {Error} | 386 * @extends {Error} |
374 */ | 387 */ |
375 cvox.SpeechRule.OutputError = function(msg) { | 388 cvox.SpeechRule.OutputError = function(msg) { |
376 this.name = 'RuleError'; | 389 this.name = 'RuleError'; |
377 this.message = msg || ''; | 390 this.message = msg || ''; |
378 }; | 391 }; |
379 goog.inherits(cvox.SpeechRule.OutputError, Error); | 392 goog.inherits(cvox.SpeechRule.OutputError, Error); |
OLD | NEW |