set_builder 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.md +35 -0
- data/Rakefile +14 -0
- data/assets/javascripts/array.js +100 -0
- data/assets/javascripts/set_builder.js +415 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/set_builder.rb +58 -0
- data/lib/set_builder/constraint.rb +67 -0
- data/lib/set_builder/modifier.rb +134 -0
- data/lib/set_builder/modifier/adverb.rb +11 -0
- data/lib/set_builder/modifier/base.rb +105 -0
- data/lib/set_builder/modifier/verb.rb +24 -0
- data/lib/set_builder/modifier_collection.rb +41 -0
- data/lib/set_builder/modifiers.rb +3 -0
- data/lib/set_builder/modifiers/date_modifier.rb +83 -0
- data/lib/set_builder/modifiers/number_modifier.rb +48 -0
- data/lib/set_builder/modifiers/string_modifier.rb +81 -0
- data/lib/set_builder/query_builders/string.rb +0 -0
- data/lib/set_builder/set.rb +81 -0
- data/lib/set_builder/trait.rb +74 -0
- data/lib/set_builder/traits.rb +42 -0
- data/lib/set_builder/value_map.rb +62 -0
- data/lib/set_builder/version.rb +3 -0
- data/set_builder.gemspec +25 -0
- data/spec/commands/example_command.rb +19 -0
- data/spec/dom.html +24 -0
- data/spec/lib/images/bg.png +0 -0
- data/spec/lib/images/hr.png +0 -0
- data/spec/lib/images/loading.gif +0 -0
- data/spec/lib/images/sprites.bg.png +0 -0
- data/spec/lib/images/sprites.png +0 -0
- data/spec/lib/images/vr.png +0 -0
- data/spec/lib/jspec.css +149 -0
- data/spec/lib/jspec.growl.js +115 -0
- data/spec/lib/jspec.jquery.js +88 -0
- data/spec/lib/jspec.js +1908 -0
- data/spec/lib/jspec.nodejs.js +18 -0
- data/spec/lib/jspec.shell.js +39 -0
- data/spec/lib/jspec.timers.js +154 -0
- data/spec/lib/jspec.xhr.js +210 -0
- data/spec/node.js +10 -0
- data/spec/rhino.js +10 -0
- data/spec/server.html +18 -0
- data/spec/server.rb +4 -0
- data/spec/unit/array.spec.js +82 -0
- data/spec/unit/set_builder.spec.js +166 -0
- data/spec/unit/spec.helper.js +0 -0
- data/test/date_modifier_test.rb +13 -0
- data/test/inflector_test.rb +27 -0
- data/test/modifier_test.rb +90 -0
- data/test/set_test.rb +96 -0
- data/test/test_helper.rb +79 -0
- data/test/trait_test.rb +49 -0
- data/test/traits_test.rb +41 -0
- data/test/value_map_test.rb +30 -0
- data/uninstall.rb +1 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ead29825b8e41af3149c07247a660207fa51c442
|
4
|
+
data.tar.gz: 04bc422d6ab418fbafa0e50d3ac2d29b529b6fef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 43424db5d5fa2ddaa21007b20299efd01b464b5034b98255ad97fa04ef2df3bdbef6548446b267c3832dbeff630344c35d7bc13577532863a16e323c1309a776
|
7
|
+
data.tar.gz: f46edcb206c607d2fa1f1ee8569a6bf0dd30e26f5821a84f84e1eb205ec3ca7ae5e327170f704cfed0b83cd13f289e8695ad03d7cb2808c695713ed443673ba8
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Bob Lail
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
SetBuilder
|
2
|
+
==========
|
3
|
+
|
4
|
+
SetBuilder's purpose is to transform _described_ data sets into queries or natural language.
|
5
|
+
|
6
|
+
|
7
|
+
Example
|
8
|
+
=======
|
9
|
+
|
10
|
+
The following set describes a group of people using simple data structures (Arrays, Strings, Symbols, and Hashes):
|
11
|
+
|
12
|
+
[[:awesome],
|
13
|
+
[:attended, "school"],
|
14
|
+
[:died, :not],
|
15
|
+
[:name, {:is => "Jerome"}]]
|
16
|
+
|
17
|
+
SetBuilder can render this set in plain English:
|
18
|
+
|
19
|
+
[Everyone] who is awesome, who attended school, who has not died, and whose name is Jerome.
|
20
|
+
|
21
|
+
It can also generate a NamedScope on an ActiveRecord model to fetch the people who fit in this set.
|
22
|
+
|
23
|
+
|
24
|
+
Usage
|
25
|
+
=====
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
Roadmap
|
30
|
+
=======
|
31
|
+
|
32
|
+
Right now SetBuilder uses ActiveRecord::NamedScope::Scope internally, but it shouldn't be hard to refactor it to use DataMapper's composable queries instead.
|
33
|
+
|
34
|
+
|
35
|
+
Copyright (c) 2010 Bob Lail, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
desc 'Run tests.'
|
5
|
+
task :default => :test
|
6
|
+
|
7
|
+
desc 'Run tests.'
|
8
|
+
Rake::TestTask.new(:test) do |t|
|
9
|
+
t.libs << 'lib'
|
10
|
+
t.libs << 'test'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,100 @@
|
|
1
|
+
/*
|
2
|
+
Extensions to core objects to provide Ruby-like idioms
|
3
|
+
===========================================================
|
4
|
+
*/
|
5
|
+
|
6
|
+
if(!Object.keys) {
|
7
|
+
Object.keys = function(o) {
|
8
|
+
var keys = [];
|
9
|
+
for(key in o) {
|
10
|
+
keys.push(key);
|
11
|
+
}
|
12
|
+
return keys;
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
//
|
19
|
+
// .toSentence
|
20
|
+
//
|
21
|
+
if(!Array.prototype.toSentence) {
|
22
|
+
Array.prototype.toSentence = function() {
|
23
|
+
switch(this.length) {
|
24
|
+
case 0:
|
25
|
+
return '';
|
26
|
+
case 1:
|
27
|
+
return this[0].toString();
|
28
|
+
case 2:
|
29
|
+
return this[0].toString() + ' and ' + this[1].toString();
|
30
|
+
default:
|
31
|
+
return this.slice(0, -1).join(', ') + ', and ' + this[this.length - 1].toString();
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
//
|
39
|
+
// .dup
|
40
|
+
//
|
41
|
+
Array.prototype.__dup = function(fn) {
|
42
|
+
return this.slice(0);
|
43
|
+
}
|
44
|
+
if(!Array.prototype.dup) Array.prototype.dup = Array.prototype.__dup;
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
//
|
49
|
+
// .each
|
50
|
+
// Distinct from Prototype's each which catches exceptions (ew!)
|
51
|
+
// so that if Prototype defines each, I can still call __each
|
52
|
+
//
|
53
|
+
Array.prototype.__each = function(fn) {
|
54
|
+
for(var i=0, len=this.length; i<len; i++) {
|
55
|
+
fn(this[i], i);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
if(!Array.prototype.each) Array.prototype.each = Array.prototype.__each;
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
//
|
63
|
+
// .collect
|
64
|
+
//
|
65
|
+
Array.prototype.__collect = function(fn) {
|
66
|
+
var new_array = [];
|
67
|
+
for(var i=0; i<this.length; i++) {
|
68
|
+
new_array.push(fn(this[i]));
|
69
|
+
}
|
70
|
+
return new_array;
|
71
|
+
}
|
72
|
+
if(!Array.prototype.collect) Array.prototype.collect = Array.prototype.__collect;
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
//
|
77
|
+
// .inject
|
78
|
+
//
|
79
|
+
Array.prototype.__inject = function(memo, fn) {
|
80
|
+
for(var i=0; i<this.length; i++) {
|
81
|
+
memo = fn(memo, this[i]);
|
82
|
+
}
|
83
|
+
return memo;
|
84
|
+
}
|
85
|
+
if(!Array.prototype.inject) Array.prototype.inject = Array.prototype.__inject;
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
//
|
90
|
+
// .find
|
91
|
+
//
|
92
|
+
Array.prototype.__find = function(fn) {
|
93
|
+
for(var i=0; i<this.length; i++) {
|
94
|
+
if(fn(this[i])) {
|
95
|
+
return this[i];
|
96
|
+
}
|
97
|
+
}
|
98
|
+
return null;
|
99
|
+
}
|
100
|
+
if(!Array.prototype.find) Array.prototype.find = Array.prototype.__find;
|
@@ -0,0 +1,415 @@
|
|
1
|
+
var SetBuilder = (function() {
|
2
|
+
|
3
|
+
var _modifiers;
|
4
|
+
var _traits;
|
5
|
+
var _value_maps = {};
|
6
|
+
|
7
|
+
return {
|
8
|
+
init: function(traits, modifiers) {
|
9
|
+
registerTraits(traits);
|
10
|
+
registerModifiers(modifiers);
|
11
|
+
},
|
12
|
+
registerTraits: function(traits) {
|
13
|
+
_traits = new SetBuilder.Traits(traits);
|
14
|
+
},
|
15
|
+
registerModifiers: function(modifiers) {
|
16
|
+
_modifiers = new SetBuilder.Modifiers(modifiers);
|
17
|
+
},
|
18
|
+
registerValueMap: function(key, map) {
|
19
|
+
_value_maps[key] = map;
|
20
|
+
},
|
21
|
+
registerValueMaps: function(_data) {
|
22
|
+
for(key in _data) {
|
23
|
+
_value_maps[key] = _data[key];
|
24
|
+
}
|
25
|
+
},
|
26
|
+
traits: function() {
|
27
|
+
return _traits;
|
28
|
+
},
|
29
|
+
modifiers: function() {
|
30
|
+
return _modifiers;
|
31
|
+
},
|
32
|
+
getValueMap: function(key) {
|
33
|
+
return _value_maps[key];
|
34
|
+
},
|
35
|
+
getValue: function(key, value) {
|
36
|
+
var match = value.toString(),
|
37
|
+
map = SetBuilder.getValueMap(key);
|
38
|
+
if(map) {
|
39
|
+
var pair = map.__find(function(i) { return (i[0] == match) });
|
40
|
+
return pair ? pair[1] : '(unknown)';
|
41
|
+
} else {
|
42
|
+
return value;
|
43
|
+
}
|
44
|
+
// map = _value_maps[key];
|
45
|
+
// return map ? map[value.toString()] : value;
|
46
|
+
},
|
47
|
+
getValueMaps: function() {
|
48
|
+
return Object.keys(_value_maps);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
})();
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
/*
|
57
|
+
Constraint (c.f. /lib/set_builder/constraint.rb)
|
58
|
+
===========================================================
|
59
|
+
|
60
|
+
a constrained trait
|
61
|
+
*/
|
62
|
+
|
63
|
+
SetBuilder.Constraint = function(_trait, args) {
|
64
|
+
|
65
|
+
var _direct_object;
|
66
|
+
if(typeof(_trait) == 'string') {
|
67
|
+
_trait = SetBuilder.traits().__find(_trait);
|
68
|
+
}
|
69
|
+
|
70
|
+
args = args.dup();
|
71
|
+
if(_trait.requires_direct_object()) _direct_object = args.shift();
|
72
|
+
var _modifiers = _trait.modifiers().collect(function(modifier_type) {
|
73
|
+
return SetBuilder.modifiers().apply(modifier_type, args.shift());
|
74
|
+
});
|
75
|
+
var _negative = false;
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
// Public methods
|
80
|
+
|
81
|
+
this.trait = function(val) {
|
82
|
+
if(val !== undefined) {
|
83
|
+
_trait = val;
|
84
|
+
_direct_object = undefined;
|
85
|
+
_modifiers = [];
|
86
|
+
}
|
87
|
+
return _trait;
|
88
|
+
}
|
89
|
+
|
90
|
+
this.direct_object = function(val) {
|
91
|
+
if(val !== undefined) {
|
92
|
+
_direct_object = val;
|
93
|
+
}
|
94
|
+
return _direct_object;
|
95
|
+
}
|
96
|
+
|
97
|
+
this.modifiers = function() {
|
98
|
+
return _modifiers;
|
99
|
+
}
|
100
|
+
|
101
|
+
this.negate = function(value) {
|
102
|
+
_negative = value;
|
103
|
+
if(_trait.noun()) _negative = false;
|
104
|
+
return this;
|
105
|
+
}
|
106
|
+
|
107
|
+
this.negative = function() {
|
108
|
+
return _negative;
|
109
|
+
}
|
110
|
+
|
111
|
+
this.requires_direct_object = function() {
|
112
|
+
return _trait.requires_direct_object();
|
113
|
+
}
|
114
|
+
|
115
|
+
this.prefix = function() {
|
116
|
+
return _trait.prefix(_negative);
|
117
|
+
}
|
118
|
+
|
119
|
+
this.toString = function(include_prefix) {
|
120
|
+
var _description = _trait.toString(include_prefix, _negative);
|
121
|
+
if(_direct_object) {
|
122
|
+
_description += ' ' + SetBuilder.getValue(_trait.direct_object_type(), _direct_object);
|
123
|
+
}
|
124
|
+
_modifiers.__each(function(modifier) {
|
125
|
+
_description += ' ' + modifier.toString(_negative);
|
126
|
+
});
|
127
|
+
return _description;
|
128
|
+
}
|
129
|
+
|
130
|
+
};
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
/*
|
135
|
+
Modifier (c.f. /lib/set_builder/modifier/base.rb)
|
136
|
+
===========================================================
|
137
|
+
|
138
|
+
|
139
|
+
*/
|
140
|
+
|
141
|
+
SetBuilder.Modifier = function(_name, _operator, _values, _params) {
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
// Public methods
|
146
|
+
|
147
|
+
this.name = function() {
|
148
|
+
return _name;
|
149
|
+
}
|
150
|
+
|
151
|
+
this.operator = function() {
|
152
|
+
return _operator;
|
153
|
+
}
|
154
|
+
|
155
|
+
this.values = function() {
|
156
|
+
return _values;
|
157
|
+
}
|
158
|
+
|
159
|
+
this.toString = function(negative) {
|
160
|
+
var words = [_operator.replace(/_/, ' ')];
|
161
|
+
for(var i=0; i<_values.length; i++) {
|
162
|
+
words.push(SetBuilder.getValue(_params[i], _values[i]));
|
163
|
+
}
|
164
|
+
return words.join(' ');
|
165
|
+
}
|
166
|
+
|
167
|
+
};
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
/*
|
172
|
+
Modifiers (c.f. /lib/set_builder/modifier.rb)
|
173
|
+
===========================================================
|
174
|
+
|
175
|
+
[
|
176
|
+
[modifier_name, {
|
177
|
+
operator: ['argument 1 type', 'argument 2 type'],
|
178
|
+
another_operator: ['argument 1 type'],
|
179
|
+
yet_another_operator: []
|
180
|
+
}]
|
181
|
+
]
|
182
|
+
*/
|
183
|
+
|
184
|
+
SetBuilder.Modifiers = function(_modifiers) {
|
185
|
+
|
186
|
+
var keys = Object.keys(_modifiers);
|
187
|
+
|
188
|
+
function _operators_for(name) {
|
189
|
+
var operators = _modifiers[name];
|
190
|
+
if(operators) {
|
191
|
+
return operators;
|
192
|
+
} else {
|
193
|
+
throw ('"' + name.toString() + '" is not a registered modifier.');
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
// Public methods
|
200
|
+
this.length = function() {
|
201
|
+
return keys.length;
|
202
|
+
}
|
203
|
+
|
204
|
+
// Returns the names of the operators allowed for the given modifier
|
205
|
+
this.operators_for = function(modifier_type) {
|
206
|
+
return Object.keys(_operators_for(modifier_type));
|
207
|
+
}
|
208
|
+
|
209
|
+
// Returns the names of the arguments a given operator anticipates
|
210
|
+
this.params_for_operator = function(modifier_type, operator_name) {
|
211
|
+
if(!operator_name) throw 'An operator name was not supplied.'
|
212
|
+
var params = _operators_for(modifier_type)[operator_name];
|
213
|
+
if(params) {
|
214
|
+
return params;
|
215
|
+
} else {
|
216
|
+
throw ('"' + operator_name.toString() + '" is not an operator for the ' + modifier_type + ' modifier.');
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
// Examples of Usage:
|
221
|
+
//
|
222
|
+
// An operator that takes one argument:
|
223
|
+
// apply('date', {'before': ['2012-11-12']})
|
224
|
+
//
|
225
|
+
// An operator that takes two arguments:
|
226
|
+
// apply('date', {'in_the_last': [5, 'days']})
|
227
|
+
//
|
228
|
+
//
|
229
|
+
// `args` is expected to be an object that has one key and one value.
|
230
|
+
//
|
231
|
+
this.apply = function(modifier_type, args) {
|
232
|
+
args = args || {};
|
233
|
+
var operator = Object.keys(args)[0];
|
234
|
+
if(!operator) throw 'An operator name was not supplied.'
|
235
|
+
|
236
|
+
var params = this.params_for_operator(modifier_type, operator);
|
237
|
+
var values = (args)[operator];
|
238
|
+
|
239
|
+
if(!(values instanceof Array)) values = [values];
|
240
|
+
if(values.length != params.length) {
|
241
|
+
throw ('The operator "' + operator.toString() + '" expects ' + params.length + ' arguments but received ' + values.length + '.');
|
242
|
+
}
|
243
|
+
|
244
|
+
return new SetBuilder.Modifier(name, operator, values, params);
|
245
|
+
}
|
246
|
+
|
247
|
+
};
|
248
|
+
|
249
|
+
|
250
|
+
|
251
|
+
/*
|
252
|
+
Set (c.f. /lib/set_builder/set.rb)
|
253
|
+
===========================================================
|
254
|
+
|
255
|
+
a set of constrained traits that describe a group
|
256
|
+
*/
|
257
|
+
|
258
|
+
SetBuilder.Set = function(_raw_data) {
|
259
|
+
|
260
|
+
if(!_raw_data) _raw_data = [];
|
261
|
+
|
262
|
+
var _constraints = [];
|
263
|
+
_raw_data.__each(function(line) {
|
264
|
+
var trait_name = line[0];
|
265
|
+
var negative = false;
|
266
|
+
if(trait_name[0] == '!') {
|
267
|
+
negative = true;
|
268
|
+
trait_name = trait_name.slice(1);
|
269
|
+
}
|
270
|
+
var trait = SetBuilder.traits().__find(trait_name);
|
271
|
+
var args = line.slice(1);
|
272
|
+
if(trait) {
|
273
|
+
_constraints.push(trait.apply(args).negate(negative));
|
274
|
+
} else if(window.console && window.console.log) {
|
275
|
+
window.console.log('trait not found with name "' + line[0] + '"');
|
276
|
+
}
|
277
|
+
});
|
278
|
+
|
279
|
+
|
280
|
+
|
281
|
+
// Public methods
|
282
|
+
|
283
|
+
this.data = function() {
|
284
|
+
|
285
|
+
// TODO: write the data structure from constraints!
|
286
|
+
|
287
|
+
}
|
288
|
+
|
289
|
+
this.constraints = function() {
|
290
|
+
return _constraints;
|
291
|
+
}
|
292
|
+
|
293
|
+
this.toString = function() {
|
294
|
+
return this.constraints().toSentence();
|
295
|
+
}
|
296
|
+
|
297
|
+
};
|
298
|
+
|
299
|
+
|
300
|
+
|
301
|
+
/*
|
302
|
+
Trait (c.f. /lib/set_builder/trait/base.rb)
|
303
|
+
===========================================================
|
304
|
+
|
305
|
+
an individual trait that can be constrained
|
306
|
+
*/
|
307
|
+
|
308
|
+
SetBuilder.Trait = function(_raw_data) {
|
309
|
+
|
310
|
+
// window.console.log('new SetBuilder.Trait()');
|
311
|
+
// window.console.log(_raw_data);
|
312
|
+
var _name = _raw_data[0];
|
313
|
+
var _part_of_speech = _raw_data[1].toString().toLowerCase();
|
314
|
+
var _modifiers = _raw_data[2] || []; //.collect(function(modifier_name) {
|
315
|
+
// return SetBuilder.Modifiers.__find(modifier_name);
|
316
|
+
// });
|
317
|
+
var _direct_object_type;
|
318
|
+
|
319
|
+
if(typeof(_name) != 'string') {
|
320
|
+
_direct_object_type = _name[1];
|
321
|
+
_name = _name[0];
|
322
|
+
}
|
323
|
+
|
324
|
+
|
325
|
+
|
326
|
+
// Public methods
|
327
|
+
|
328
|
+
this.requires_direct_object = function() {
|
329
|
+
return !!_direct_object_type;
|
330
|
+
}
|
331
|
+
|
332
|
+
this.direct_object_type = function() {
|
333
|
+
return _direct_object_type;
|
334
|
+
}
|
335
|
+
|
336
|
+
this.name = function() {
|
337
|
+
return _name;
|
338
|
+
}
|
339
|
+
|
340
|
+
this.noun = function() {
|
341
|
+
return (_part_of_speech == 'noun');
|
342
|
+
}
|
343
|
+
|
344
|
+
this.modifiers = function() {
|
345
|
+
return _modifiers;
|
346
|
+
}
|
347
|
+
|
348
|
+
this.prefix = function(negative) {
|
349
|
+
if(negative === undefined) negative = false;
|
350
|
+
switch(_part_of_speech) {
|
351
|
+
case 'active':
|
352
|
+
return negative ? 'who have not' : 'who';
|
353
|
+
case 'perfect':
|
354
|
+
return negative ? 'who have not' : 'who have';
|
355
|
+
case 'passive':
|
356
|
+
return negative ? 'who were not' : 'who were';
|
357
|
+
case 'reflexive':
|
358
|
+
return negative ? 'who are not' : 'who are';
|
359
|
+
case 'noun':
|
360
|
+
return 'whose';
|
361
|
+
default:
|
362
|
+
return undefined;
|
363
|
+
}
|
364
|
+
}
|
365
|
+
|
366
|
+
this.toString = function(include_prefix, negative) {
|
367
|
+
var prefix = this.prefix(negative);
|
368
|
+
if(prefix) { // return an empty string if the prefix is invalid
|
369
|
+
return (include_prefix==false) ? this.name() : (prefix + ' ' + this.name());
|
370
|
+
} else {
|
371
|
+
return '';
|
372
|
+
}
|
373
|
+
}
|
374
|
+
|
375
|
+
this.apply = function(args) {
|
376
|
+
return new SetBuilder.Constraint(this, args);
|
377
|
+
}
|
378
|
+
|
379
|
+
};
|
380
|
+
|
381
|
+
|
382
|
+
|
383
|
+
/*
|
384
|
+
Traits (c.f. /lib/set_builder/traits.rb)
|
385
|
+
===========================================================
|
386
|
+
|
387
|
+
a collection of traits that allows fetching by name
|
388
|
+
*/
|
389
|
+
|
390
|
+
SetBuilder.Traits = function(_raw_data) {
|
391
|
+
|
392
|
+
var _traits = _raw_data.collect(function(line) {
|
393
|
+
return new SetBuilder.Trait(line);
|
394
|
+
});
|
395
|
+
|
396
|
+
|
397
|
+
// Public methods
|
398
|
+
|
399
|
+
this.length = function() {
|
400
|
+
return _traits.length;
|
401
|
+
}
|
402
|
+
|
403
|
+
this.names = function() {
|
404
|
+
return _traits.collect(function(trait) {
|
405
|
+
return trait.name();
|
406
|
+
});
|
407
|
+
}
|
408
|
+
|
409
|
+
this.__find = function(name) {
|
410
|
+
return _traits.__find(function(trait) {
|
411
|
+
return (trait.name() == name);
|
412
|
+
});
|
413
|
+
}
|
414
|
+
|
415
|
+
};
|