tr8n_core 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +69 -0
  4. data/Rakefile +9 -0
  5. data/config/config.yml +34 -0
  6. data/config/tokens/data.yml +45 -0
  7. data/config/tokens/decorations.yml +37 -0
  8. data/lib/tr8n/application.rb +320 -0
  9. data/lib/tr8n/base.rb +123 -0
  10. data/lib/tr8n/cache.rb +144 -0
  11. data/lib/tr8n/cache_adapters/cdb.rb +74 -0
  12. data/lib/tr8n/cache_adapters/file.rb +70 -0
  13. data/lib/tr8n/cache_adapters/memcache.rb +91 -0
  14. data/lib/tr8n/cache_adapters/redis.rb +94 -0
  15. data/lib/tr8n/component.rb +68 -0
  16. data/lib/tr8n/config.rb +291 -0
  17. data/lib/tr8n/decorators/base.rb +35 -0
  18. data/lib/tr8n/decorators/default.rb +30 -0
  19. data/lib/tr8n/decorators/html.rb +63 -0
  20. data/lib/tr8n/exception.rb +26 -0
  21. data/lib/tr8n/language.rb +250 -0
  22. data/lib/tr8n/language_case.rb +116 -0
  23. data/lib/tr8n/language_case_rule.rb +85 -0
  24. data/lib/tr8n/language_context.rb +115 -0
  25. data/lib/tr8n/language_context_rule.rb +62 -0
  26. data/lib/tr8n/logger.rb +83 -0
  27. data/lib/tr8n/rules_engine/evaluator.rb +156 -0
  28. data/lib/tr8n/rules_engine/parser.rb +83 -0
  29. data/lib/tr8n/source.rb +95 -0
  30. data/lib/tr8n/tokens/data.rb +410 -0
  31. data/lib/tr8n/tokens/data_tokenizer.rb +82 -0
  32. data/lib/tr8n/tokens/decoration_tokenizer.rb +200 -0
  33. data/lib/tr8n/tokens/hidden.rb +48 -0
  34. data/lib/tr8n/tokens/method.rb +52 -0
  35. data/lib/tr8n/tokens/transform.rb +191 -0
  36. data/lib/tr8n/translation.rb +104 -0
  37. data/lib/tr8n/translation_key.rb +205 -0
  38. data/lib/tr8n/translator.rb +62 -0
  39. data/lib/tr8n/utils.rb +124 -0
  40. data/lib/tr8n_core/ext/array.rb +74 -0
  41. data/lib/tr8n_core/ext/date.rb +63 -0
  42. data/lib/tr8n_core/ext/fixnum.rb +39 -0
  43. data/lib/tr8n_core/ext/hash.rb +126 -0
  44. data/lib/tr8n_core/ext/string.rb +44 -0
  45. data/lib/tr8n_core/ext/time.rb +71 -0
  46. data/lib/tr8n_core/generators/cache/base.rb +85 -0
  47. data/lib/tr8n_core/generators/cache/cdb.rb +27 -0
  48. data/lib/tr8n_core/generators/cache/file.rb +69 -0
  49. data/lib/tr8n_core/modules/logger.rb +43 -0
  50. data/lib/tr8n_core/version.rb +27 -0
  51. data/lib/tr8n_core.rb +68 -0
  52. data/spec/application_spec.rb +228 -0
  53. data/spec/base_spec.rb +19 -0
  54. data/spec/config_spec.rb +16 -0
  55. data/spec/decorator_spec.rb +10 -0
  56. data/spec/decorators/base_spec.rb +14 -0
  57. data/spec/decorators/default_spec.rb +12 -0
  58. data/spec/decorators/html_spec.rb +50 -0
  59. data/spec/fixtures/application.json +112 -0
  60. data/spec/fixtures/languages/en-US.json +1424 -0
  61. data/spec/fixtures/languages/es.json +291 -0
  62. data/spec/fixtures/languages/ru.json +550 -0
  63. data/spec/fixtures/translations/ru/basic.json +56 -0
  64. data/spec/fixtures/translations/ru/counters.json +43 -0
  65. data/spec/fixtures/translations/ru/genders.json +171 -0
  66. data/spec/fixtures/translations/ru/last_names.txt +200 -0
  67. data/spec/fixtures/translations/ru/names.json +1 -0
  68. data/spec/fixtures/translations/ru/names.txt +458 -0
  69. data/spec/helper.rb +84 -0
  70. data/spec/language_case_rule_spec.rb +57 -0
  71. data/spec/language_case_spec.rb +58 -0
  72. data/spec/language_context_rule_spec.rb +73 -0
  73. data/spec/language_context_spec.rb +331 -0
  74. data/spec/language_spec.rb +16 -0
  75. data/spec/rules_engine/evaluator_spec.rb +148 -0
  76. data/spec/rules_engine/parser_spec.rb +29 -0
  77. data/spec/tokens/data_spec.rb +160 -0
  78. data/spec/tokens/data_tokenizer_spec.rb +29 -0
  79. data/spec/tokens/decoration_tokenizer_spec.rb +81 -0
  80. data/spec/tokens/hidden_spec.rb +24 -0
  81. data/spec/tokens/method_spec.rb +84 -0
  82. data/spec/tokens/transform_spec.rb +50 -0
  83. data/spec/translation_key_spec.rb +96 -0
  84. data/spec/translation_spec.rb +24 -0
  85. data/spec/utils_spec.rb +64 -0
  86. metadata +176 -0
@@ -0,0 +1,550 @@
1
+ {
2
+ "locale":"ru",
3
+ "name":"Русский",
4
+ "english_name":"Russian",
5
+ "native_name":"Русский",
6
+ "flag_url":"http://localhost:3000/media/54/39/11/49/cb768f030bde97f97.png",
7
+ "curse_words":"блядь",
8
+ "contexts":{
9
+ "date":{
10
+ "keyword":"date",
11
+ "keys":[
12
+ "past",
13
+ "present",
14
+ "future"
15
+ ],
16
+ "default_key":"present",
17
+ "token_expression":"/.*(date|time)(\\d)*$/",
18
+ "variables":[
19
+ "@date"
20
+ ],
21
+ "token_mapping":[
22
+ "unsupported",
23
+ "unsupported",
24
+ {
25
+ "past":"{$0}",
26
+ "present":"{$1}",
27
+ "future":"{$2}"
28
+ }
29
+ ],
30
+ "rules":{
31
+ "future":{
32
+ "keyword":"future",
33
+ "description":"{token} is in the past",
34
+ "conditions":"(< @date (today))",
35
+ "conditions_expression":[
36
+ "<",
37
+ "@date",
38
+ [
39
+ "today"
40
+ ]
41
+ ]
42
+ },
43
+ "past":{
44
+ "keyword":"past",
45
+ "description":"{token} is in the future",
46
+ "conditions":"(> @date (today))",
47
+ "conditions_expression":[
48
+ ">",
49
+ "@date",
50
+ [
51
+ "today"
52
+ ]
53
+ ]
54
+ },
55
+ "present":{
56
+ "keyword":"present",
57
+ "description":"{token} is in the present",
58
+ "conditions":"(= @date (today))",
59
+ "conditions_expression":[
60
+ "=",
61
+ "@date",
62
+ [
63
+ "today"
64
+ ]
65
+ ]
66
+ }
67
+ }
68
+ },
69
+ "gender":{
70
+ "keyword":"gender",
71
+ "keys":[
72
+ "male",
73
+ "female",
74
+ "other"
75
+ ],
76
+ "default_key":"other",
77
+ "token_expression":"/.*(user|translator|profile|actor|target)(\\d)*$/",
78
+ "variables":[
79
+ "@gender"
80
+ ],
81
+ "token_mapping":[
82
+ {
83
+ "other":"{$0}"
84
+ },
85
+ {
86
+ "male":"{$0}",
87
+ "female":"{$1}",
88
+ "other":"{$0}/{$1}"
89
+ },
90
+ {
91
+ "male":"{$0}",
92
+ "female":"{$1}",
93
+ "other":"{$2}"
94
+ }
95
+ ],
96
+ "rules":{
97
+ "female":{
98
+ "keyword":"female",
99
+ "description":"{token} is a female",
100
+ "conditions":"(= 'female' @gender)",
101
+ "conditions_expression":[
102
+ "=",
103
+ "female",
104
+ "@gender"
105
+ ]
106
+ },
107
+ "male":{
108
+ "keyword":"male",
109
+ "description":"{token} is a male",
110
+ "conditions":"(= 'male' @gender)",
111
+ "conditions_expression":[
112
+ "=",
113
+ "male",
114
+ "@gender"
115
+ ]
116
+ },
117
+ "other":{
118
+ "keyword":"other",
119
+ "description":"{token}'s gender is unknown"
120
+ }
121
+ }
122
+ },
123
+ "genders":{
124
+ "keyword":"genders",
125
+ "keys":[
126
+ "male",
127
+ "female",
128
+ "unknown",
129
+ "other"
130
+ ],
131
+ "default_key":"other",
132
+ "token_expression":"/.*(users|profiles|actors|targets)(\\d)*$/",
133
+ "variables":[
134
+ "@genders"
135
+ ],
136
+ "token_mapping":[
137
+ "unsupported",
138
+ "unsupported",
139
+ "unsupported",
140
+ {
141
+ "male":"{$0}",
142
+ "female":"{$1}",
143
+ "unknown":"{$2}",
144
+ "other":"{$3}"
145
+ }
146
+ ],
147
+ "rules":{
148
+ "female":{
149
+ "keyword":"female",
150
+ "description":"{token} contains 1 female",
151
+ "conditions":"(&& (= 1 (count @genders)) (all @genders 'female'))",
152
+ "conditions_expression":[
153
+ "&&",
154
+ [
155
+ "=",
156
+ 1,
157
+ [
158
+ "count",
159
+ "@genders"
160
+ ]
161
+ ],
162
+ [
163
+ "all",
164
+ "@genders",
165
+ "female"
166
+ ]
167
+ ]
168
+ },
169
+ "male":{
170
+ "keyword":"male",
171
+ "description":"{token} contains 1 male",
172
+ "conditions":"(&& (= 1 (count @genders)) (all @genders 'male'))",
173
+ "conditions_expression":[
174
+ "&&",
175
+ [
176
+ "=",
177
+ 1,
178
+ [
179
+ "count",
180
+ "@genders"
181
+ ]
182
+ ],
183
+ [
184
+ "all",
185
+ "@genders",
186
+ "male"
187
+ ]
188
+ ]
189
+ },
190
+ "other":{
191
+ "keyword":"other",
192
+ "description":"{token} contains at least 2 people"
193
+ },
194
+ "unknown":{
195
+ "keyword":"unknown",
196
+ "description":"{token} contains 1 person with unknown gender",
197
+ "conditions":"(&& (= 1 (count @genders)) (all @genders 'unknown'))",
198
+ "conditions_expression":[
199
+ "&&",
200
+ [
201
+ "=",
202
+ 1,
203
+ [
204
+ "count",
205
+ "@genders"
206
+ ]
207
+ ],
208
+ [
209
+ "all",
210
+ "@genders",
211
+ "unknown"
212
+ ]
213
+ ]
214
+ }
215
+ }
216
+ },
217
+ "list":{
218
+ "keyword":"list",
219
+ "keys":[
220
+ "one",
221
+ "other"
222
+ ],
223
+ "default_key":"other",
224
+ "token_expression":"/.*(items|list)(\\d)*$/",
225
+ "variables":[
226
+ "@count"
227
+ ],
228
+ "token_mapping":[
229
+ "unsupported",
230
+ {
231
+ "one":"{$0}",
232
+ "other":"{$1}"
233
+ }
234
+ ],
235
+ "rules":{
236
+ "one":{
237
+ "keyword":"one",
238
+ "description":"{token} contains 1 element",
239
+ "conditions":"(= 1 @count)",
240
+ "conditions_expression":[
241
+ "=",
242
+ 1,
243
+ "@count"
244
+ ]
245
+ },
246
+ "other":{
247
+ "keyword":"other",
248
+ "description":"{token} contains at least 2 elements"
249
+ }
250
+ }
251
+ },
252
+ "number":{
253
+ "keyword":"number",
254
+ "keys":[
255
+ "one",
256
+ "few",
257
+ "many",
258
+ "other"
259
+ ],
260
+ "default_key":"many",
261
+ "token_expression":"/.*(count|num|minutes|seconds|hours|sum|total)(\\d)*$/",
262
+ "variables":[
263
+ "@n"
264
+ ],
265
+ "token_mapping":[
266
+ "unsupported",
267
+ "unsupported",
268
+ {
269
+ "one":"{$0}",
270
+ "few":"{$1}",
271
+ "many":"${2}",
272
+ "other":"{$2}"
273
+ },
274
+ {
275
+ "one":"{$0}",
276
+ "few":"{$1}",
277
+ "many":"${2}",
278
+ "other":"{$3}"
279
+ }
280
+ ],
281
+ "rules":{
282
+ "few":{
283
+ "keyword":"few",
284
+ "description":"{token} mod 10 in 2..4 and {token} mod 100 not in 12..14",
285
+ "examples":"2-4, 22-24, 32-34...",
286
+ "conditions":"(&& (in '2..4' (mod @n 10)) (not (in '12..14' (mod @n 100))))",
287
+ "conditions_expression":[
288
+ "&&",
289
+ [
290
+ "in",
291
+ "2..4",
292
+ [
293
+ "mod",
294
+ "@n",
295
+ 10
296
+ ]
297
+ ],
298
+ [
299
+ "not",
300
+ [
301
+ "in",
302
+ "12..14",
303
+ [
304
+ "mod",
305
+ "@n",
306
+ 100
307
+ ]
308
+ ]
309
+ ]
310
+ ]
311
+ },
312
+ "many":{
313
+ "keyword":"many",
314
+ "description":"{token} mod 10 is 0 or {token} mod 10 in 5..9 or {token} mod 100 in 11..14",
315
+ "examples":"0, 5-20, 25-30, 35-40...",
316
+ "conditions":"(|| (= 0 (mod @n 10)) (in '5..9' (mod @n 10)) (in '11..14' (mod @n 100)))",
317
+ "conditions_expression":[
318
+ "||",
319
+ [
320
+ "=",
321
+ 0,
322
+ [
323
+ "mod",
324
+ "@n",
325
+ 10
326
+ ]
327
+ ],
328
+ [
329
+ "in",
330
+ "5..9",
331
+ [
332
+ "mod",
333
+ "@n",
334
+ 10
335
+ ]
336
+ ],
337
+ [
338
+ "in",
339
+ "11..14",
340
+ [
341
+ "mod",
342
+ "@n",
343
+ 100
344
+ ]
345
+ ]
346
+ ]
347
+ },
348
+ "one":{
349
+ "keyword":"one",
350
+ "description":"{token} mod 10 is 1 and {token} mod 100 is not 11",
351
+ "examples":"1, 21, 31, 41, 51, 61...",
352
+ "conditions":"(&& (= 1 (mod @n 10)) (!= 11 (mod @n 100)))",
353
+ "conditions_expression":[
354
+ "&&",
355
+ [
356
+ "=",
357
+ 1,
358
+ [
359
+ "mod",
360
+ "@n",
361
+ 10
362
+ ]
363
+ ],
364
+ [
365
+ "!=",
366
+ 11,
367
+ [
368
+ "mod",
369
+ "@n",
370
+ 100
371
+ ]
372
+ ]
373
+ ]
374
+ },
375
+ "other":{
376
+ "keyword":"other",
377
+ "examples":"1.2, 2.07, 5.94..."
378
+ }
379
+ }
380
+ },
381
+ "value":{
382
+ "keyword":"value",
383
+ "keys":[
384
+ "vowel",
385
+ "other"
386
+ ],
387
+ "default_key":"vowel",
388
+ "token_expression":"/.*$/",
389
+ "variables":[
390
+ "@value"
391
+ ],
392
+ "token_mapping":[
393
+ "unsupported",
394
+ {
395
+ "vowel":"{$0}",
396
+ "con":"{$1}"
397
+ }
398
+ ],
399
+ "rules":{
400
+ "other":{
401
+ "keyword":"other",
402
+ "description":"{token} starts with a consonant",
403
+ "examples":"б, в, г, д, к..."
404
+ },
405
+ "vowel":{
406
+ "keyword":"vowel",
407
+ "description":"{token} starts with a vowel",
408
+ "examples":"а, и, о, у, ы, э",
409
+ "conditions":[
410
+ "match",
411
+ "/^[аиоуыэАИОУЭ]/",
412
+ "@value"
413
+ ],
414
+ "conditions_expression":[
415
+ "match",
416
+ "/^[аиоуыэАИОУЭ]/",
417
+ "@value"
418
+ ]
419
+ }
420
+ }
421
+ }
422
+ },
423
+ "cases":{
424
+ "acc":{
425
+ "id":85,
426
+ "keyword":"acc",
427
+ "latin_name":"Accusativus",
428
+ "native_name":"Винительный падеж",
429
+ "description":"Вижу - Кого? Что?",
430
+ "application":"words",
431
+ "rules":[
432
+
433
+ ]
434
+ },
435
+ "dat":{
436
+ "id":86,
437
+ "keyword":"dat",
438
+ "latin_name":"Dativus",
439
+ "native_name":"Дательный падеж",
440
+ "description":"Рад - Кому? Чему?",
441
+ "application":"words",
442
+ "rules":[
443
+ {
444
+ "id":927,
445
+ "description":"If ends in 'л', append 'у'.",
446
+ "examples":"Михаил => Михаилу",
447
+ "conditions":"(match '/л$/' @value)",
448
+ "conditions_expression":[
449
+ "match",
450
+ "/л$/",
451
+ "@value"
452
+ ],
453
+ "operations":"(append 'у' @value)",
454
+ "operations_expression":[
455
+ "append",
456
+ "у",
457
+ "@value"
458
+ ]
459
+ },
460
+ {
461
+ "id":926,
462
+ "description":"If ends in 'a', replace with 'e'",
463
+ "examples":"Анна => Анне",
464
+ "conditions":"(match '/а$/' @value)",
465
+ "conditions_expression":[
466
+ "match",
467
+ "/а$/",
468
+ "@value"
469
+ ],
470
+ "operations":"(replace '/а$/' 'е' @value)",
471
+ "operations_expression":[
472
+ "replace",
473
+ "/а$/",
474
+ "е",
475
+ "@value"
476
+ ]
477
+ }
478
+ ]
479
+ },
480
+ "gen":{
481
+ "id":87,
482
+ "keyword":"gen",
483
+ "latin_name":"Genitivus",
484
+ "native_name":"Родительный падеж",
485
+ "description":"Нет - Кого? Чего?",
486
+ "application":"words",
487
+ "rules":[
488
+ {
489
+ "id":925,
490
+ "conditions":"(match '/[бвгджзклмнпрстфхцчшщ]$/' @value)",
491
+ "conditions_expression":[
492
+ "match",
493
+ "/[бвгджзклмнпрстфхцчшщ]$/",
494
+ "@value"
495
+ ],
496
+ "operations":"(append 'a' @value)",
497
+ "operations_expression":[
498
+ "append",
499
+ "a",
500
+ "@value"
501
+ ]
502
+ }
503
+ ]
504
+ },
505
+ "ins":{
506
+ "id":88,
507
+ "keyword":"ins",
508
+ "latin_name":"Instrumentalis",
509
+ "native_name":"Творительный падеж",
510
+ "description":"Доволен - Кем? Чем?",
511
+ "application":"words",
512
+ "rules":[
513
+
514
+ ]
515
+ },
516
+ "nom":{
517
+ "id":89,
518
+ "keyword":"nom",
519
+ "latin_name":"Nominativus",
520
+ "native_name":"Именительный падеж",
521
+ "description":"Есть - Кто? Что?",
522
+ "application":"words",
523
+ "rules":[
524
+
525
+ ]
526
+ },
527
+ "pos":{
528
+ "id":90,
529
+ "keyword":"pos",
530
+ "latin_name":"Possessive",
531
+ "native_name":"Притяжательный падеж",
532
+ "description":"Чей?",
533
+ "application":"words",
534
+ "rules":[
535
+
536
+ ]
537
+ },
538
+ "pre":{
539
+ "id":91,
540
+ "keyword":"pre",
541
+ "latin_name":"Prepositivus",
542
+ "native_name":"Предложный падеж",
543
+ "description":"Думаю - О ком? О чём?",
544
+ "application":"words",
545
+ "rules":[
546
+
547
+ ]
548
+ }
549
+ }
550
+ }
@@ -0,0 +1,56 @@
1
+ [{
2
+ "label": "Hello World",
3
+ "translations": {
4
+ "ru": [
5
+ {
6
+ "label": "Привет Мир"
7
+ }
8
+ ]
9
+ }
10
+ }, {
11
+ "label": "Hello World",
12
+ "description": "Greeting context",
13
+ "translations": {
14
+ "ru": [
15
+ {
16
+ "label": "Привет Мир"
17
+ }
18
+ ]
19
+ }
20
+ }, {
21
+ "label": "Hello [i: World]",
22
+ "translations": {
23
+ "ru": [
24
+ {
25
+ "label": "Привет [i: Мир]"
26
+ }
27
+ ]
28
+ }
29
+ }, {
30
+ "label": "Hello [i: {user}]",
31
+ "translations": {
32
+ "ru": [
33
+ {
34
+ "label": "Привет [i: {user}]"
35
+ }
36
+ ]
37
+ }
38
+ }, {
39
+ "label": "Hello {user.first_name} [i: {user.last_name}]",
40
+ "translations": {
41
+ "ru": [
42
+ {
43
+ "label": "Привет {user.first_name} [i: {user.last_name}]"
44
+ }
45
+ ]
46
+ }
47
+ }, {
48
+ "label": "Hello {user}",
49
+ "translations": {
50
+ "ru": [
51
+ {
52
+ "label": "Привет {user}"
53
+ }
54
+ ]
55
+ }
56
+ }]
@@ -0,0 +1,43 @@
1
+ [{
2
+ "label": "{count||message}",
3
+ "translations": {
4
+ "ru": [
5
+ {
6
+ "label": "{count} сообщение",
7
+ "locale": "ru",
8
+ "context": {
9
+ "count": [
10
+ {
11
+ "type": "number",
12
+ "key": "one"
13
+ }
14
+ ]
15
+ }
16
+ },
17
+ {
18
+ "label": "{count} сообщения",
19
+ "locale": "ru",
20
+ "context": {
21
+ "count": [
22
+ {
23
+ "type": "number",
24
+ "key": "few"
25
+ }
26
+ ]
27
+ }
28
+ },
29
+ {
30
+ "label": "{count} сообщений",
31
+ "locale": "ru",
32
+ "context": {
33
+ "count": [
34
+ {
35
+ "type": "number",
36
+ "key": "many"
37
+ }
38
+ ]
39
+ }
40
+ }
41
+ ]
42
+ }
43
+ }]