tml 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +243 -0
  4. data/Rakefile +9 -0
  5. data/lib/tml.rb +56 -0
  6. data/lib/tml/api/client.rb +206 -0
  7. data/lib/tml/api/post_office.rb +71 -0
  8. data/lib/tml/application.rb +254 -0
  9. data/lib/tml/base.rb +116 -0
  10. data/lib/tml/cache.rb +143 -0
  11. data/lib/tml/cache_adapters/file.rb +89 -0
  12. data/lib/tml/cache_adapters/memcache.rb +104 -0
  13. data/lib/tml/cache_adapters/memory.rb +85 -0
  14. data/lib/tml/cache_adapters/redis.rb +108 -0
  15. data/lib/tml/config.rb +410 -0
  16. data/lib/tml/decorators/base.rb +52 -0
  17. data/lib/tml/decorators/default.rb +43 -0
  18. data/lib/tml/decorators/html.rb +102 -0
  19. data/lib/tml/exception.rb +35 -0
  20. data/lib/tml/ext/array.rb +86 -0
  21. data/lib/tml/ext/date.rb +99 -0
  22. data/lib/tml/ext/fixnum.rb +47 -0
  23. data/lib/tml/ext/hash.rb +99 -0
  24. data/lib/tml/ext/string.rb +56 -0
  25. data/lib/tml/ext/time.rb +89 -0
  26. data/lib/tml/generators/cache/base.rb +117 -0
  27. data/lib/tml/generators/cache/file.rb +159 -0
  28. data/lib/tml/language.rb +175 -0
  29. data/lib/tml/language_case.rb +105 -0
  30. data/lib/tml/language_case_rule.rb +76 -0
  31. data/lib/tml/language_context.rb +117 -0
  32. data/lib/tml/language_context_rule.rb +56 -0
  33. data/lib/tml/languages/en.json +1363 -0
  34. data/lib/tml/logger.rb +109 -0
  35. data/lib/tml/rules_engine/evaluator.rb +162 -0
  36. data/lib/tml/rules_engine/parser.rb +65 -0
  37. data/lib/tml/session.rb +199 -0
  38. data/lib/tml/source.rb +106 -0
  39. data/lib/tml/tokenizers/data.rb +96 -0
  40. data/lib/tml/tokenizers/decoration.rb +204 -0
  41. data/lib/tml/tokenizers/dom.rb +346 -0
  42. data/lib/tml/tokens/data.rb +403 -0
  43. data/lib/tml/tokens/method.rb +61 -0
  44. data/lib/tml/tokens/transform.rb +223 -0
  45. data/lib/tml/translation.rb +67 -0
  46. data/lib/tml/translation_key.rb +178 -0
  47. data/lib/tml/translator.rb +47 -0
  48. data/lib/tml/utils.rb +130 -0
  49. data/lib/tml/version.rb +34 -0
  50. metadata +121 -0
@@ -0,0 +1,56 @@
1
+ # encoding: UTF-8
2
+ #--
3
+ # Copyright (c) 2015 Translation Exchange, Inc
4
+ #
5
+ # _______ _ _ _ ______ _
6
+ # |__ __| | | | | (_) | ____| | |
7
+ # | |_ __ __ _ _ __ ___| | __ _| |_ _ ___ _ __ | |__ __ _____| |__ __ _ _ __ __ _ ___
8
+ # | | '__/ _` | '_ \/ __| |/ _` | __| |/ _ \| '_ \| __| \ \/ / __| '_ \ / _` | '_ \ / _` |/ _ \
9
+ # | | | | (_| | | | \__ \ | (_| | |_| | (_) | | | | |____ > < (__| | | | (_| | | | | (_| | __/
10
+ # |_|_| \__,_|_| |_|___/_|\__,_|\__|_|\___/|_| |_|______/_/\_\___|_| |_|\__,_|_| |_|\__, |\___|
11
+ # __/ |
12
+ # |___/
13
+ # Permission is hereby granted, free of charge, to any person obtaining
14
+ # a copy of this software and associated documentation files (the
15
+ # "Software"), to deal in the Software without restriction, including
16
+ # without limitation the rights to use, copy, modify, merge, publish,
17
+ # distribute, sublicense, and/or sell copies of the Software, and to
18
+ # permit persons to whom the Software is furnished to do so, subject to
19
+ # the following conditions:
20
+ #
21
+ # The above copyright notice and this permission notice shall be
22
+ # included in all copies or substantial portions of the Software.
23
+ #
24
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ #++
32
+
33
+ class Tml::LanguageContextRule < Tml::Base
34
+ belongs_to :language_context
35
+ attributes :keyword, :description, :examples, :conditions, :conditions_expression
36
+
37
+ def fallback?
38
+ self.keyword.to_s.to_sym == :other
39
+ end
40
+
41
+ def conditions_expression
42
+ self.attributes[:conditions_expression] ||= Tml::RulesEngine::Parser.new(self.conditions).parse
43
+ end
44
+
45
+ def evaluate(vars = {})
46
+ return true if fallback?
47
+
48
+ re = Tml::RulesEngine::Evaluator.new
49
+ vars.each do |key, value|
50
+ re.evaluate(['let', key, value])
51
+ end
52
+
53
+ re.evaluate(conditions_expression)
54
+ end
55
+
56
+ end
@@ -0,0 +1,1363 @@
1
+ {"locale":"en",
2
+ "name":"English",
3
+ "flag_url": "https://translationexchange.com/media/7/55/1/27/c9262c9538cda82c6.png",
4
+ "contexts":{
5
+ "date":{
6
+ "keyword":"date",
7
+ "keys":[
8
+ "past",
9
+ "present",
10
+ "future"
11
+ ],
12
+ "default_key":"present",
13
+ "token_expression":"/.*(date|time)(\\d)*$/",
14
+ "variables":[
15
+ "@date"
16
+ ],
17
+ "token_mapping":[
18
+ "unsupported",
19
+ "unsupported",
20
+ {
21
+ "past":"{$0}",
22
+ "present":"{$1}",
23
+ "future":"{$2}"
24
+ }
25
+ ],
26
+ "rules":{
27
+ "future":{
28
+ "keyword":"future",
29
+ "description":"{token} is in the past",
30
+ "conditions":"(< @date (today))",
31
+ "conditions_expression":[
32
+ "<",
33
+ "@date",
34
+ [
35
+ "today"
36
+ ]
37
+ ]
38
+ },
39
+ "past":{
40
+ "keyword":"past",
41
+ "description":"{token} is in the future",
42
+ "conditions":"(> @date (today))",
43
+ "conditions_expression":[
44
+ ">",
45
+ "@date",
46
+ [
47
+ "today"
48
+ ]
49
+ ]
50
+ },
51
+ "present":{
52
+ "keyword":"present",
53
+ "description":"{token} is in the present",
54
+ "conditions":"(= @date (today))",
55
+ "conditions_expression":[
56
+ "=",
57
+ "@date",
58
+ [
59
+ "today"
60
+ ]
61
+ ]
62
+ }
63
+ }
64
+ },
65
+ "gender":{
66
+ "keyword":"gender",
67
+ "keys":[
68
+ "male",
69
+ "female",
70
+ "other"
71
+ ],
72
+ "default_key":"other",
73
+ "token_expression":"/.*(user|translator|profile|actor|target)(\\d)*$/",
74
+ "variables":[
75
+ "@gender"
76
+ ],
77
+ "token_mapping":[
78
+ {
79
+ "other":"{$0}"
80
+ },
81
+ {
82
+ "male":"{$0}",
83
+ "female":"{$1}",
84
+ "other":"{$0}/{$1}"
85
+ },
86
+ {
87
+ "male":"{$0}",
88
+ "female":"{$1}",
89
+ "other":"{$2}"
90
+ }
91
+ ],
92
+ "rules":{
93
+ "male":{
94
+ "keyword":"male",
95
+ "description":"{token} is a male",
96
+ "conditions":"(= 'male' @gender)",
97
+ "conditions_expression":[
98
+ "=",
99
+ "male",
100
+ "@gender"
101
+ ]
102
+ },
103
+ "female":{
104
+ "keyword":"female",
105
+ "description":"{token} is a female",
106
+ "conditions":"(= 'female' @gender)",
107
+ "conditions_expression":[
108
+ "=",
109
+ "female",
110
+ "@gender"
111
+ ]
112
+ },
113
+ "other":{
114
+ "keyword":"other",
115
+ "description":"{token}'s gender is unknown"
116
+ }
117
+ }
118
+ },
119
+ "genders":{
120
+ "keyword":"genders",
121
+ "description":"",
122
+ "keys":[
123
+ "male",
124
+ "female",
125
+ "unknown",
126
+ "other"
127
+ ],
128
+ "default_key":"other",
129
+ "token_expression":"/.*(users|profiles|actors|targets)(\\d)*$/",
130
+ "variables":[
131
+ "@genders"
132
+ ],
133
+ "token_mapping":[
134
+ "unsupported",
135
+ {
136
+ "male":"{$0}",
137
+ "female":"{$0}",
138
+ "unknown":"{$1}",
139
+ "other":"{$1}"
140
+ },
141
+ {
142
+ "male":"{$0}",
143
+ "female":"{$1}",
144
+ "unknown":"{$1}",
145
+ "other":"{$2}"
146
+ },
147
+ {
148
+ "male":"{$0}",
149
+ "female":"{$1}",
150
+ "unknown":"{$2}",
151
+ "other":"{$3}"
152
+ }
153
+ ],
154
+ "rules":{
155
+ "male":{
156
+ "keyword":"male",
157
+ "description":"{token} contains 1 male",
158
+ "conditions":"(&& (= 1 (count @genders)) (all @genders 'male'))",
159
+ "conditions_expression":[
160
+ "&&",
161
+ [
162
+ "=",
163
+ 1,
164
+ [
165
+ "count",
166
+ "@genders"
167
+ ]
168
+ ],
169
+ [
170
+ "all",
171
+ "@genders",
172
+ "male"
173
+ ]
174
+ ]
175
+ },
176
+ "female":{
177
+ "keyword":"female",
178
+ "description":"{token} contains 1 female",
179
+ "conditions":"(&& (= 1 (count @genders)) (all @genders 'female'))",
180
+ "conditions_expression":[
181
+ "&&",
182
+ [
183
+ "=",
184
+ 1,
185
+ [
186
+ "count",
187
+ "@genders"
188
+ ]
189
+ ],
190
+ [
191
+ "all",
192
+ "@genders",
193
+ "female"
194
+ ]
195
+ ]
196
+ },
197
+ "unknown":{
198
+ "keyword":"unknown",
199
+ "description":"{token} contains 1 person with unknown gender",
200
+ "conditions":"(&& (= 1 (count @genders)) (all @genders 'unknown'))",
201
+ "conditions_expression":[
202
+ "&&",
203
+ [
204
+ "=",
205
+ 1,
206
+ [
207
+ "count",
208
+ "@genders"
209
+ ]
210
+ ],
211
+ [
212
+ "all",
213
+ "@genders",
214
+ "unknown"
215
+ ]
216
+ ]
217
+ },
218
+ "other":{
219
+ "keyword":"other",
220
+ "description":"{token} contains at least 2 people"
221
+ }
222
+ }
223
+ },
224
+ "list":{
225
+ "keyword":"list",
226
+ "keys":[
227
+ "one",
228
+ "other"
229
+ ],
230
+ "default_key":"other",
231
+ "token_expression":"/.*(items|list)(\\d)*$/",
232
+ "variables":[
233
+ "@count"
234
+ ],
235
+ "token_mapping":[
236
+ "unsupported",
237
+ {
238
+ "one":"{$0}",
239
+ "other":"{$1}"
240
+ }
241
+ ],
242
+ "rules":{
243
+ "one":{
244
+ "keyword":"one",
245
+ "description":"{token} contains 1 element",
246
+ "conditions":"(= 1 @count)",
247
+ "conditions_expression":[
248
+ "=",
249
+ 1,
250
+ "@count"
251
+ ]
252
+ },
253
+ "other":{
254
+ "keyword":"other",
255
+ "description":"{token} contains at least 2 elements"
256
+ }
257
+ }
258
+ },
259
+ "number":{
260
+ "keyword":"number",
261
+ "keys":[
262
+ "one",
263
+ "other"
264
+ ],
265
+ "default_key":"other",
266
+ "token_expression":"/.*(count|num|minutes|seconds|hours|sum|total)(\\d)*$/",
267
+ "variables":[
268
+ "@n"
269
+ ],
270
+ "token_mapping":[
271
+ {
272
+ "one":"{$0}",
273
+ "other":"{$0::plural}"
274
+ },
275
+ {
276
+ "one":"{$0}",
277
+ "other":"{$1}"
278
+ }
279
+ ],
280
+ "rules":{
281
+ "one":{
282
+ "keyword":"one",
283
+ "description":"{token} is 1",
284
+ "examples":"1",
285
+ "conditions":"(= @n 1)",
286
+ "conditions_expression":[
287
+ "=",
288
+ "@n",
289
+ 1
290
+ ]
291
+ },
292
+ "other":{
293
+ "keyword":"other",
294
+ "description":"{token} is not 1",
295
+ "examples":"0, 2-999; 1.2, 2.07..."
296
+ }
297
+ }
298
+ }
299
+ },
300
+ "cases":{
301
+ "plural":{
302
+ "keyword":"plural",
303
+ "latin_name":"Plural",
304
+ "description":"Converts singular form to plural",
305
+ "application":"phrase",
306
+ "rules":[
307
+ {
308
+ "description":"Uncountable word",
309
+ "conditions":"(in 'sheep,fish,series,species,money,rice,information,equipment' @value)",
310
+ "conditions_expression":[
311
+ "in",
312
+ "sheep,fish,series,species,money,rice,information,equipment",
313
+ "@value"
314
+ ],
315
+ "operations":"@value",
316
+ "operations_expression":"@value"
317
+ },
318
+ {
319
+ "description":"Irregular word",
320
+ "conditions":"(= 'move' @value)",
321
+ "conditions_expression":[
322
+ "=",
323
+ "move",
324
+ "@value"
325
+ ],
326
+ "operations":"(quote 'moves')",
327
+ "operations_expression":[
328
+ "quote",
329
+ "moves"
330
+ ]
331
+ },
332
+ {
333
+ "description":"Irregular word",
334
+ "conditions":"(= 'sex' @value)",
335
+ "conditions_expression":[
336
+ "=",
337
+ "sex",
338
+ "@value"
339
+ ],
340
+ "operations":"(quote 'sexes')",
341
+ "operations_expression":[
342
+ "quote",
343
+ "sexes"
344
+ ]
345
+ },
346
+ {
347
+ "description":"Irregular word",
348
+ "conditions":"(= 'child' @value)",
349
+ "conditions_expression":[
350
+ "=",
351
+ "child",
352
+ "@value"
353
+ ],
354
+ "operations":"(quote 'children')",
355
+ "operations_expression":[
356
+ "quote",
357
+ "children"
358
+ ]
359
+ },
360
+ {
361
+ "description":"Irregular word",
362
+ "conditions":"(= 'person' @value)",
363
+ "conditions_expression":[
364
+ "=",
365
+ "person",
366
+ "@value"
367
+ ],
368
+ "operations":"(quote 'people')",
369
+ "operations_expression":[
370
+ "quote",
371
+ "people"
372
+ ]
373
+ },
374
+ {
375
+ "conditions":"(match '/(quiz)$/i' @value)",
376
+ "conditions_expression":[
377
+ "match",
378
+ "/(quiz)$/i",
379
+ "@value"
380
+ ],
381
+ "operations":"(replace '/(quiz)$/i' '$1zes' @value)",
382
+ "operations_expression":[
383
+ "replace",
384
+ "/(quiz)$/i",
385
+ "$1zes",
386
+ "@value"
387
+ ]
388
+ },
389
+ {
390
+ "conditions":"(match '/^(ox)$/i' @value)",
391
+ "conditions_expression":[
392
+ "match",
393
+ "/^(ox)$/i",
394
+ "@value"
395
+ ],
396
+ "operations":"(replace '/^(ox)$/i' '$1en' @value)",
397
+ "operations_expression":[
398
+ "replace",
399
+ "/^(ox)$/i",
400
+ "$1en",
401
+ "@value"
402
+ ]
403
+ },
404
+ {
405
+ "conditions":"(match '/([m|l])ouse$/i' @value)",
406
+ "conditions_expression":[
407
+ "match",
408
+ "/([m|l])ouse$/i",
409
+ "@value"
410
+ ],
411
+ "operations":"(replace '/([m|l])ouse$/i' '$1ice' @value)",
412
+ "operations_expression":[
413
+ "replace",
414
+ "/([m|l])ouse$/i",
415
+ "$1ice",
416
+ "@value"
417
+ ]
418
+ },
419
+ {
420
+ "conditions":"(match '/(matr|vert|ind)ix|ex$/i' @value)",
421
+ "conditions_expression":[
422
+ "match",
423
+ "/(matr|vert|ind)ix|ex$/i",
424
+ "@value"
425
+ ],
426
+ "operations":"(replace '/(matr|vert|ind)ix|ex$/i' '$1ices' @value)",
427
+ "operations_expression":[
428
+ "replace",
429
+ "/(matr|vert|ind)ix|ex$/i",
430
+ "$1ices",
431
+ "@value"
432
+ ]
433
+ },
434
+ {
435
+ "conditions":"(match '/(x|ch|ss|sh)$/i' @value)",
436
+ "conditions_expression":[
437
+ "match",
438
+ "/(x|ch|ss|sh)$/i",
439
+ "@value"
440
+ ],
441
+ "operations":"(replace '/(x|ch|ss|sh)$/i' '$1es' @value)",
442
+ "operations_expression":[
443
+ "replace",
444
+ "/(x|ch|ss|sh)$/i",
445
+ "$1es",
446
+ "@value"
447
+ ]
448
+ },
449
+ {
450
+ "conditions":"(match '/([^aeiouy]|qu)y$/i' @value)",
451
+ "conditions_expression":[
452
+ "match",
453
+ "/([^aeiouy]|qu)y$/i",
454
+ "@value"
455
+ ],
456
+ "operations":"(replace '/([^aeiouy]|qu)y$/i' '$1ies' @value)",
457
+ "operations_expression":[
458
+ "replace",
459
+ "/([^aeiouy]|qu)y$/i",
460
+ "$1ies",
461
+ "@value"
462
+ ]
463
+ },
464
+ {
465
+ "conditions":"(match '/([^aeiouy]|qu)ies$/i' @value)",
466
+ "conditions_expression":[
467
+ "match",
468
+ "/([^aeiouy]|qu)ies$/i",
469
+ "@value"
470
+ ],
471
+ "operations":"(replace '/([^aeiouy]|qu)ies$/i' '$1y' @value)",
472
+ "operations_expression":[
473
+ "replace",
474
+ "/([^aeiouy]|qu)ies$/i",
475
+ "$1y",
476
+ "@value"
477
+ ]
478
+ },
479
+ {
480
+ "conditions":"(match '/(hive)$/i' @value)",
481
+ "conditions_expression":[
482
+ "match",
483
+ "/(hive)$/i",
484
+ "@value"
485
+ ],
486
+ "operations":"(replace '/(hive)$/i' '$1s' @value)",
487
+ "operations_expression":[
488
+ "replace",
489
+ "/(hive)$/i",
490
+ "$1s",
491
+ "@value"
492
+ ]
493
+ },
494
+ {
495
+ "conditions":"(match '/(?:([^f])fe|([lr])f)$/i' @value)",
496
+ "conditions_expression":[
497
+ "match",
498
+ "/(?:([^f])fe|([lr])f)$/i",
499
+ "@value"
500
+ ],
501
+ "operations":"(replace '/(?:([^f])fe|([lr])f)$/i' '$1$2ves' @value)",
502
+ "operations_expression":[
503
+ "replace",
504
+ "/(?:([^f])fe|([lr])f)$/i",
505
+ "$1$2ves",
506
+ "@value"
507
+ ]
508
+ },
509
+ {
510
+ "conditions":"(match '/sis$/i' @value)",
511
+ "conditions_expression":[
512
+ "match",
513
+ "/sis$/i",
514
+ "@value"
515
+ ],
516
+ "operations":"(replace '/sis$/i' 'ses' @value)",
517
+ "operations_expression":[
518
+ "replace",
519
+ "/sis$/i",
520
+ "ses",
521
+ "@value"
522
+ ]
523
+ },
524
+ {
525
+ "conditions":"(match '/([ti])um$/i' @value)",
526
+ "conditions_expression":[
527
+ "match",
528
+ "/([ti])um$/i",
529
+ "@value"
530
+ ],
531
+ "operations":"(replace '/([ti])um$/i' '$1a' @value)",
532
+ "operations_expression":[
533
+ "replace",
534
+ "/([ti])um$/i",
535
+ "$1a",
536
+ "@value"
537
+ ]
538
+ },
539
+ {
540
+ "conditions":"(match '/(buffal|tomat|potat)o$/i' @value)",
541
+ "conditions_expression":[
542
+ "match",
543
+ "/(buffal|tomat|potat)o$/i",
544
+ "@value"
545
+ ],
546
+ "operations":"(replace '/(buffal|tomat|potat)o$/i' '$1oes' @value)",
547
+ "operations_expression":[
548
+ "replace",
549
+ "/(buffal|tomat|potat)o$/i",
550
+ "$1oes",
551
+ "@value"
552
+ ]
553
+ },
554
+ {
555
+ "conditions":"(match '/(bu)s$/i' @value)",
556
+ "conditions_expression":[
557
+ "match",
558
+ "/(bu)s$/i",
559
+ "@value"
560
+ ],
561
+ "operations":"(replace '/(bu)s$/i' '$1ses' @value)",
562
+ "operations_expression":[
563
+ "replace",
564
+ "/(bu)s$/i",
565
+ "$1ses",
566
+ "@value"
567
+ ]
568
+ },
569
+ {
570
+ "conditions":"(match '/(alias|status)$/i' @value)",
571
+ "conditions_expression":[
572
+ "match",
573
+ "/(alias|status)$/i",
574
+ "@value"
575
+ ],
576
+ "operations":"(replace '/(alias|status)$/i' '$1es' @value)",
577
+ "operations_expression":[
578
+ "replace",
579
+ "/(alias|status)$/i",
580
+ "$1es",
581
+ "@value"
582
+ ]
583
+ },
584
+ {
585
+ "conditions":"(match '/(octop)us$/i' @value)",
586
+ "conditions_expression":[
587
+ "match",
588
+ "/(octop)us$/i",
589
+ "@value"
590
+ ],
591
+ "operations":"(replace '/(octop)us$/i' '$1i' @value)",
592
+ "operations_expression":[
593
+ "replace",
594
+ "/(octop)us$/i",
595
+ "$1i",
596
+ "@value"
597
+ ]
598
+ },
599
+ {
600
+ "conditions":"(match '/(ax|test)is$/i' @value)",
601
+ "conditions_expression":[
602
+ "match",
603
+ "/(ax|test)is$/i",
604
+ "@value"
605
+ ],
606
+ "operations":"(replace '/(ax|test)is$/i' '$1es' @value)",
607
+ "operations_expression":[
608
+ "replace",
609
+ "/(ax|test)is$/i",
610
+ "$1es",
611
+ "@value"
612
+ ]
613
+ },
614
+ {
615
+ "conditions":"(match '/us$/i' @value)",
616
+ "conditions_expression":[
617
+ "match",
618
+ "/us$/i",
619
+ "@value"
620
+ ],
621
+ "operations":"(replace '/us$/i' '$1es' @value)",
622
+ "operations_expression":[
623
+ "replace",
624
+ "/us$/i",
625
+ "$1es",
626
+ "@value"
627
+ ]
628
+ },
629
+ {
630
+ "conditions":"(match '/s$/i' @value)",
631
+ "conditions_expression":[
632
+ "match",
633
+ "/s$/i",
634
+ "@value"
635
+ ],
636
+ "operations":"(replace '/s$/i' 's' @value)",
637
+ "operations_expression":[
638
+ "replace",
639
+ "/s$/i",
640
+ "s",
641
+ "@value"
642
+ ]
643
+ },
644
+ {
645
+ "conditions":"(match '/$/' @value)",
646
+ "conditions_expression":[
647
+ "match",
648
+ "/$/",
649
+ "@value"
650
+ ],
651
+ "operations":"(replace '/$/' 's' @value)",
652
+ "operations_expression":[
653
+ "replace",
654
+ "/$/",
655
+ "s",
656
+ "@value"
657
+ ]
658
+ }
659
+ ]
660
+ },
661
+ "singular":{
662
+ "keyword":"singular",
663
+ "latin_name":"Singular",
664
+ "description":"Converts plural form to singular",
665
+ "application":"phrase",
666
+ "rules":[
667
+ {
668
+ "description":"Uncountable word",
669
+ "conditions":"(in 'sheep,fish,series,species,money,rice,information,equipment' @value)",
670
+ "conditions_expression":[
671
+ "in",
672
+ "sheep,fish,series,species,money,rice,information,equipment",
673
+ "@value"
674
+ ],
675
+ "operations":"@value",
676
+ "operations_expression":"@value"
677
+ },
678
+ {
679
+ "description":"Irregular word",
680
+ "conditions":"(= 'moves' @value)",
681
+ "conditions_expression":[
682
+ "=",
683
+ "moves",
684
+ "@value"
685
+ ],
686
+ "operations":"(quote 'move')",
687
+ "operations_expression":[
688
+ "quote",
689
+ "move"
690
+ ]
691
+ },
692
+ {
693
+ "description":"Irregular word",
694
+ "conditions":"(= 'sexes' @value)",
695
+ "conditions_expression":[
696
+ "=",
697
+ "sexes",
698
+ "@value"
699
+ ],
700
+ "operations":"(quote 'sex')",
701
+ "operations_expression":[
702
+ "quote",
703
+ "sex"
704
+ ]
705
+ },
706
+ {
707
+ "description":"Irregular word",
708
+ "conditions":"(= 'children' @value)",
709
+ "conditions_expression":[
710
+ "=",
711
+ "children",
712
+ "@value"
713
+ ],
714
+ "operations":"(quote 'child')",
715
+ "operations_expression":[
716
+ "quote",
717
+ "child"
718
+ ]
719
+ },
720
+ {
721
+ "description":"Irregular word",
722
+ "conditions":"(= 'people' @value)",
723
+ "conditions_expression":[
724
+ "=",
725
+ "people",
726
+ "@value"
727
+ ],
728
+ "operations":"(quote 'person')",
729
+ "operations_expression":[
730
+ "quote",
731
+ "person"
732
+ ]
733
+ },
734
+ {
735
+ "conditions":"(match '/(n)ews$/i' @value)",
736
+ "conditions_expression":[
737
+ "match",
738
+ "/(n)ews$/i",
739
+ "@value"
740
+ ],
741
+ "operations":"(replace '/(n)ews$/i' '$1ews' @value)",
742
+ "operations_expression":[
743
+ "replace",
744
+ "/(n)ews$/i",
745
+ "$1ews",
746
+ "@value"
747
+ ]
748
+ },
749
+ {
750
+ "conditions":"(match '/([ti])a$/i' @value)",
751
+ "conditions_expression":[
752
+ "match",
753
+ "/([ti])a$/i",
754
+ "@value"
755
+ ],
756
+ "operations":"(replace '/([ti])a$/i' '$1um' @value)",
757
+ "operations_expression":[
758
+ "replace",
759
+ "/([ti])a$/i",
760
+ "$1um",
761
+ "@value"
762
+ ]
763
+ },
764
+ {
765
+ "conditions":"(match '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' @value)",
766
+ "conditions_expression":[
767
+ "match",
768
+ "/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i",
769
+ "@value"
770
+ ],
771
+ "operations":"(replace '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' '$1$2sis' @value)",
772
+ "operations_expression":[
773
+ "replace",
774
+ "/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i",
775
+ "$1$2sis",
776
+ "@value"
777
+ ]
778
+ },
779
+ {
780
+ "conditions":"(match '/(^analy)ses$/i' @value)",
781
+ "conditions_expression":[
782
+ "match",
783
+ "/(^analy)ses$/i",
784
+ "@value"
785
+ ],
786
+ "operations":"(replace '/(^analy)ses$/i' '$1sis' @value)",
787
+ "operations_expression":[
788
+ "replace",
789
+ "/(^analy)ses$/i",
790
+ "$1sis",
791
+ "@value"
792
+ ]
793
+ },
794
+ {
795
+ "conditions":"(match '/([^f])ves$/i' @value)",
796
+ "conditions_expression":[
797
+ "match",
798
+ "/([^f])ves$/i",
799
+ "@value"
800
+ ],
801
+ "operations":"(replace '/([^f])ves$/i' '$1fe' @value)",
802
+ "operations_expression":[
803
+ "replace",
804
+ "/([^f])ves$/i",
805
+ "$1fe",
806
+ "@value"
807
+ ]
808
+ },
809
+ {
810
+ "conditions":"(match '/(hive)s$/i' @value)",
811
+ "conditions_expression":[
812
+ "match",
813
+ "/(hive)s$/i",
814
+ "@value"
815
+ ],
816
+ "operations":"(replace '/(hive)s$/i' '$1' @value)",
817
+ "operations_expression":[
818
+ "replace",
819
+ "/(hive)s$/i",
820
+ "$1",
821
+ "@value"
822
+ ]
823
+ },
824
+ {
825
+ "conditions":"(match '/(tive)s$/i' @value)",
826
+ "conditions_expression":[
827
+ "match",
828
+ "/(tive)s$/i",
829
+ "@value"
830
+ ],
831
+ "operations":"(replace '/(tive)s$/i' '$1' @value)",
832
+ "operations_expression":[
833
+ "replace",
834
+ "/(tive)s$/i",
835
+ "$1",
836
+ "@value"
837
+ ]
838
+ },
839
+ {
840
+ "conditions":"(match '/([lr])ves$/i' @value)",
841
+ "conditions_expression":[
842
+ "match",
843
+ "/([lr])ves$/i",
844
+ "@value"
845
+ ],
846
+ "operations":"(replace '/([lr])ves$/i' '$1f' @value)",
847
+ "operations_expression":[
848
+ "replace",
849
+ "/([lr])ves$/i",
850
+ "$1f",
851
+ "@value"
852
+ ]
853
+ },
854
+ {
855
+ "conditions":"(match '/([^aeiouy]|qu)ies$/i' @value)",
856
+ "conditions_expression":[
857
+ "match",
858
+ "/([^aeiouy]|qu)ies$/i",
859
+ "@value"
860
+ ],
861
+ "operations":"(replace '/([^aeiouy]|qu)ies$/i' '$1y' @value)",
862
+ "operations_expression":[
863
+ "replace",
864
+ "/([^aeiouy]|qu)ies$/i",
865
+ "$1y",
866
+ "@value"
867
+ ]
868
+ },
869
+ {
870
+ "conditions":"(match '/(s)eries$/i' @value)",
871
+ "conditions_expression":[
872
+ "match",
873
+ "/(s)eries$/i",
874
+ "@value"
875
+ ],
876
+ "operations":"(replace '/(s)eries$/i' '$1eries' @value)",
877
+ "operations_expression":[
878
+ "replace",
879
+ "/(s)eries$/i",
880
+ "$1eries",
881
+ "@value"
882
+ ]
883
+ },
884
+ {
885
+ "conditions":"(match '/(m)ovies$/i' @value)",
886
+ "conditions_expression":[
887
+ "match",
888
+ "/(m)ovies$/i",
889
+ "@value"
890
+ ],
891
+ "operations":"(replace '/(m)ovies$/i' '$1ovie' @value)",
892
+ "operations_expression":[
893
+ "replace",
894
+ "/(m)ovies$/i",
895
+ "$1ovie",
896
+ "@value"
897
+ ]
898
+ },
899
+ {
900
+ "conditions":"(match '/(x|ch|ss|sh)es$/i' @value)",
901
+ "conditions_expression":[
902
+ "match",
903
+ "/(x|ch|ss|sh)es$/i",
904
+ "@value"
905
+ ],
906
+ "operations":"(replace '/(x|ch|ss|sh)es$/i' '$1' @value)",
907
+ "operations_expression":[
908
+ "replace",
909
+ "/(x|ch|ss|sh)es$/i",
910
+ "$1",
911
+ "@value"
912
+ ]
913
+ },
914
+ {
915
+ "conditions":"(match '/([m|l])ice$/i' @value)",
916
+ "conditions_expression":[
917
+ "match",
918
+ "/([m|l])ice$/i",
919
+ "@value"
920
+ ],
921
+ "operations":"(replace '/([m|l])ice$/i' '$1ouse' @value)",
922
+ "operations_expression":[
923
+ "replace",
924
+ "/([m|l])ice$/i",
925
+ "$1ouse",
926
+ "@value"
927
+ ]
928
+ },
929
+ {
930
+ "conditions":"(match '/(bus)es$/i' @value)",
931
+ "conditions_expression":[
932
+ "match",
933
+ "/(bus)es$/i",
934
+ "@value"
935
+ ],
936
+ "operations":"(replace '/(bus)es$/i' '$1' @value)",
937
+ "operations_expression":[
938
+ "replace",
939
+ "/(bus)es$/i",
940
+ "$1",
941
+ "@value"
942
+ ]
943
+ },
944
+ {
945
+ "conditions":"(match '/(o)es$/i' @value)",
946
+ "conditions_expression":[
947
+ "match",
948
+ "/(o)es$/i",
949
+ "@value"
950
+ ],
951
+ "operations":"(replace '/(o)es$/i' '$1' @value)",
952
+ "operations_expression":[
953
+ "replace",
954
+ "/(o)es$/i",
955
+ "$1",
956
+ "@value"
957
+ ]
958
+ },
959
+ {
960
+ "conditions":"(match '/(shoe)s$/i' @value)",
961
+ "conditions_expression":[
962
+ "match",
963
+ "/(shoe)s$/i",
964
+ "@value"
965
+ ],
966
+ "operations":"(replace '/(shoe)s$/i' '$1' @value)",
967
+ "operations_expression":[
968
+ "replace",
969
+ "/(shoe)s$/i",
970
+ "$1",
971
+ "@value"
972
+ ]
973
+ },
974
+ {
975
+ "conditions":"(match '/(cris|ax|test)es$/i' @value)",
976
+ "conditions_expression":[
977
+ "match",
978
+ "/(cris|ax|test)es$/i",
979
+ "@value"
980
+ ],
981
+ "operations":"(replace '/(cris|ax|test)es$/i' '$1is' @value)",
982
+ "operations_expression":[
983
+ "replace",
984
+ "/(cris|ax|test)es$/i",
985
+ "$1is",
986
+ "@value"
987
+ ]
988
+ },
989
+ {
990
+ "conditions":"(match '/(octop|vir)i$/i' @value)",
991
+ "conditions_expression":[
992
+ "match",
993
+ "/(octop|vir)i$/i",
994
+ "@value"
995
+ ],
996
+ "operations":"(replace '/(octop|vir)i$/i' '$1us' @value)",
997
+ "operations_expression":[
998
+ "replace",
999
+ "/(octop|vir)i$/i",
1000
+ "$1us",
1001
+ "@value"
1002
+ ]
1003
+ },
1004
+ {
1005
+ "conditions":"(match '/(alias|status)es$/i' @value)",
1006
+ "conditions_expression":[
1007
+ "match",
1008
+ "/(alias|status)es$/i",
1009
+ "@value"
1010
+ ],
1011
+ "operations":"(replace '/(alias|status)es$/i' '$1' @value)",
1012
+ "operations_expression":[
1013
+ "replace",
1014
+ "/(alias|status)es$/i",
1015
+ "$1",
1016
+ "@value"
1017
+ ]
1018
+ },
1019
+ {
1020
+ "conditions":"(match '/^(ox)en$/i' @value)",
1021
+ "conditions_expression":[
1022
+ "match",
1023
+ "/^(ox)en$/i",
1024
+ "@value"
1025
+ ],
1026
+ "operations":"(replace '/^(ox)en$/i' '$1' @value)",
1027
+ "operations_expression":[
1028
+ "replace",
1029
+ "/^(ox)en$/i",
1030
+ "$1",
1031
+ "@value"
1032
+ ]
1033
+ },
1034
+ {
1035
+ "conditions":"(match '/(vert|ind)ices$/i' @value)",
1036
+ "conditions_expression":[
1037
+ "match",
1038
+ "/(vert|ind)ices$/i",
1039
+ "@value"
1040
+ ],
1041
+ "operations":"(replace '/(vert|ind)ices$/i' '$1ex' @value)",
1042
+ "operations_expression":[
1043
+ "replace",
1044
+ "/(vert|ind)ices$/i",
1045
+ "$1ex",
1046
+ "@value"
1047
+ ]
1048
+ },
1049
+ {
1050
+ "conditions":"(match '/(matr)ices$/i' @value)",
1051
+ "conditions_expression":[
1052
+ "match",
1053
+ "/(matr)ices$/i",
1054
+ "@value"
1055
+ ],
1056
+ "operations":"(replace '/(matr)ices$/i' '$1ix' @value)",
1057
+ "operations_expression":[
1058
+ "replace",
1059
+ "/(matr)ices$/i",
1060
+ "$1ix",
1061
+ "@value"
1062
+ ]
1063
+ },
1064
+ {
1065
+ "conditions":"(match '/(quiz)zes$/i' @value)",
1066
+ "conditions_expression":[
1067
+ "match",
1068
+ "/(quiz)zes$/i",
1069
+ "@value"
1070
+ ],
1071
+ "operations":"(replace '/(quiz)zes$/i' '$1' @value)",
1072
+ "operations_expression":[
1073
+ "replace",
1074
+ "/(quiz)zes$/i",
1075
+ "$1",
1076
+ "@value"
1077
+ ]
1078
+ },
1079
+ {
1080
+ "conditions":"(match '/(us)es$/i' @value)",
1081
+ "conditions_expression":[
1082
+ "match",
1083
+ "/(us)es$/i",
1084
+ "@value"
1085
+ ],
1086
+ "operations":"(replace '/(us)es$/i' '$1' @value)",
1087
+ "operations_expression":[
1088
+ "replace",
1089
+ "/(us)es$/i",
1090
+ "$1",
1091
+ "@value"
1092
+ ]
1093
+ },
1094
+ {
1095
+ "conditions":"(match '/s$/i' @value)",
1096
+ "conditions_expression":[
1097
+ "match",
1098
+ "/s$/i",
1099
+ "@value"
1100
+ ],
1101
+ "operations":"(replace '/s$/i' '' @value)",
1102
+ "operations_expression":[
1103
+ "replace",
1104
+ "/s$/i",
1105
+ "",
1106
+ "@value"
1107
+ ]
1108
+ }
1109
+ ]
1110
+ },
1111
+ "pos":{
1112
+ "keyword":"pos",
1113
+ "latin_name":"Possessive",
1114
+ "description":"Used to indicate possession (i.e., ownership). It is usually created by adding 's to the word",
1115
+ "application":"phrase",
1116
+ "rules":[
1117
+ {
1118
+ "description":"if value ends in s, append '",
1119
+ "conditions":"(match '/s$/' @value)",
1120
+ "conditions_expression":[
1121
+ "match",
1122
+ "/s$/",
1123
+ "@value"
1124
+ ],
1125
+ "operations":"(append \"'\" @value)",
1126
+ "operations_expression":[
1127
+ "append",
1128
+ "'",
1129
+ "@value"
1130
+ ]
1131
+ },
1132
+ {
1133
+ "description":"in all other cases, append 's",
1134
+ "conditions":"(true)",
1135
+ "conditions_expression":[
1136
+ "true"
1137
+ ],
1138
+ "operations":"(append \"'s\" @value)",
1139
+ "operations_expression":[
1140
+ "append",
1141
+ "'s",
1142
+ "@value"
1143
+ ]
1144
+ }
1145
+ ]
1146
+ },
1147
+ "ord":{
1148
+ "keyword":"ord",
1149
+ "latin_name":"Ordinal",
1150
+ "native_name":"Short Ordinal",
1151
+ "description":"The adjective form of the cardinal numbers",
1152
+ "application":"phrase",
1153
+ "rules":[
1154
+ {
1155
+ "id":727,
1156
+ "description":"append 'st' if value ends in 1, but not in 11",
1157
+ "examples":"1, 21, 31, 41, 101, 121...",
1158
+ "conditions":"(&& (match '/1$/' @value) (! (match '/11$/' @value)))",
1159
+ "conditions_expression":[
1160
+ "&&",
1161
+ [
1162
+ "match",
1163
+ "/1$/",
1164
+ "@value"
1165
+ ],
1166
+ [
1167
+ "!",
1168
+ [
1169
+ "match",
1170
+ "/11$/",
1171
+ "@value"
1172
+ ]
1173
+ ]
1174
+ ],
1175
+ "operations":"(append 'st' @value)",
1176
+ "operations_expression":[
1177
+ "append",
1178
+ "st",
1179
+ "@value"
1180
+ ]
1181
+ },
1182
+ {
1183
+ "description":"append 'nd' if value ends in 2, but not in 12",
1184
+ "examples":"2, 22, 32, 42, 102, 122...",
1185
+ "conditions":"(&& (match '/2$/' @value) (! (match '/12$/' @value)))",
1186
+ "conditions_expression":[
1187
+ "&&",
1188
+ [
1189
+ "match",
1190
+ "/2$/",
1191
+ "@value"
1192
+ ],
1193
+ [
1194
+ "!",
1195
+ [
1196
+ "match",
1197
+ "/12$/",
1198
+ "@value"
1199
+ ]
1200
+ ]
1201
+ ],
1202
+ "operations":"(append 'nd' @value)",
1203
+ "operations_expression":[
1204
+ "append",
1205
+ "nd",
1206
+ "@value"
1207
+ ]
1208
+ },
1209
+ {
1210
+ "description":"append 'nd' if value ends in 3, but not in 13",
1211
+ "examples":"3, 23, 33, 43, 103, 123...",
1212
+ "conditions":"(&& (match '/3$/' @value) (! (match '/13$/' @value)))",
1213
+ "conditions_expression":[
1214
+ "&&",
1215
+ [
1216
+ "match",
1217
+ "/3$/",
1218
+ "@value"
1219
+ ],
1220
+ [
1221
+ "!",
1222
+ [
1223
+ "match",
1224
+ "/13$/",
1225
+ "@value"
1226
+ ]
1227
+ ]
1228
+ ],
1229
+ "operations":"(append 'rd' @value)",
1230
+ "operations_expression":[
1231
+ "append",
1232
+ "rd",
1233
+ "@value"
1234
+ ]
1235
+ },
1236
+ {
1237
+ "description":"append 'th' in all other cases",
1238
+ "examples":"0, 4, 5, 6, 7, 8, 9, 11, 12, 13, 111, 113...",
1239
+ "conditions":"(true)",
1240
+ "conditions_expression":[
1241
+ "true"
1242
+ ],
1243
+ "operations":"(append 'th' @value)",
1244
+ "operations_expression":[
1245
+ "append",
1246
+ "th",
1247
+ "@value"
1248
+ ]
1249
+ }
1250
+ ]
1251
+ },
1252
+ "ordinal":{
1253
+ "keyword":"ordinal",
1254
+ "latin_name":"Ordinal",
1255
+ "native_name":"Full Ordinal",
1256
+ "description":"The adjective form of the cardinal numbers",
1257
+ "application":"phrase",
1258
+ "rules":[
1259
+ {
1260
+ "description":"replace 1 with 'first'",
1261
+ "conditions":"(= 1 @value)",
1262
+ "conditions_expression":[
1263
+ "=",
1264
+ 1,
1265
+ "@value"
1266
+ ],
1267
+ "operations":"(replace 1 'first' @value)",
1268
+ "operations_expression":[
1269
+ "replace",
1270
+ 1,
1271
+ "first",
1272
+ "@value"
1273
+ ]
1274
+ },
1275
+ {
1276
+ "description":"replace 2 with 'second'",
1277
+ "conditions":"(= 2 @value)",
1278
+ "conditions_expression":[
1279
+ "=",
1280
+ 2,
1281
+ "@value"
1282
+ ],
1283
+ "operations":"(replace 2 'first' @value)",
1284
+ "operations_expression":[
1285
+ "replace",
1286
+ 2,
1287
+ "first",
1288
+ "@value"
1289
+ ]
1290
+ },
1291
+ {
1292
+ "description":"replace 3 with 'third'",
1293
+ "conditions":"(= 3 @value)",
1294
+ "conditions_expression":[
1295
+ "=",
1296
+ 3,
1297
+ "@value"
1298
+ ],
1299
+ "operations":"(replace 3 'third' @value)",
1300
+ "operations_expression":[
1301
+ "replace",
1302
+ 3,
1303
+ "third",
1304
+ "@value"
1305
+ ]
1306
+ }
1307
+ ]
1308
+ },
1309
+ "times":{
1310
+ "keyword":"times",
1311
+ "latin_name":"Iteration",
1312
+ "description":"The iteration form of the cardinal numbers",
1313
+ "application":"phrase",
1314
+ "rules":[
1315
+ {
1316
+ "description":"replace '1' with 'once'",
1317
+ "conditions":"(= 1 @value)",
1318
+ "conditions_expression":[
1319
+ "=",
1320
+ 1,
1321
+ "@value"
1322
+ ],
1323
+ "operations":"(replace '1' 'once' @value)",
1324
+ "operations_expression":[
1325
+ "replace",
1326
+ "1",
1327
+ "once",
1328
+ "@value"
1329
+ ]
1330
+ },
1331
+ {
1332
+ "description":"replace '2' with 'twice'",
1333
+ "conditions":"(= 2 @value)",
1334
+ "conditions_expression":[
1335
+ "=",
1336
+ 2,
1337
+ "@value"
1338
+ ],
1339
+ "operations":"(replace '2' 'twice' @value)",
1340
+ "operations_expression":[
1341
+ "replace",
1342
+ "2",
1343
+ "twice",
1344
+ "@value"
1345
+ ]
1346
+ },
1347
+ {
1348
+ "description":"in all other cases, append x times",
1349
+ "conditions":"(true)",
1350
+ "conditions_expression":[
1351
+ "true"
1352
+ ],
1353
+ "operations":"(append ' times' @value)",
1354
+ "operations_expression":[
1355
+ "append",
1356
+ " times",
1357
+ "@value"
1358
+ ]
1359
+ }
1360
+ ]
1361
+ }
1362
+ }
1363
+ }