set_builder 1.0.2
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.
- 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
|
+
};
|