llt-helpers 0.0.4
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 +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +8 -0
- data/lib/llt/helpers.rb +15 -0
- data/lib/llt/helpers/configuration.rb +44 -0
- data/lib/llt/helpers/constantize.rb +25 -0
- data/lib/llt/helpers/equality.rb +28 -0
- data/lib/llt/helpers/functions.rb +26 -0
- data/lib/llt/helpers/initialize.rb +28 -0
- data/lib/llt/helpers/metrical.rb +31 -0
- data/lib/llt/helpers/normalizer.rb +28 -0
- data/lib/llt/helpers/pluralize.rb +23 -0
- data/lib/llt/helpers/positions.rb +93 -0
- data/lib/llt/helpers/primitive_cache.rb +37 -0
- data/lib/llt/helpers/query_methods.rb +30 -0
- data/lib/llt/helpers/roman_numerals.rb +50 -0
- data/lib/llt/helpers/terminology.rb +219 -0
- data/lib/llt/helpers/transformer.rb +33 -0
- data/lib/llt/helpers/version.rb +5 -0
- data/llt-helpers.gemspec +27 -0
- data/spec/lib/llt/helpers/configuration_spec.rb +77 -0
- data/spec/lib/llt/helpers/constantize_spec.rb +79 -0
- data/spec/lib/llt/helpers/equality_spec.rb +48 -0
- data/spec/lib/llt/helpers/functions_spec.rb +47 -0
- data/spec/lib/llt/helpers/initialize_spec.rb +50 -0
- data/spec/lib/llt/helpers/metrical_spec.rb +40 -0
- data/spec/lib/llt/helpers/normalizer_spec.rb +57 -0
- data/spec/lib/llt/helpers/pluralize_spec.rb +38 -0
- data/spec/lib/llt/helpers/positions_spec.rb +108 -0
- data/spec/lib/llt/helpers/primitive_cache_spec.rb +65 -0
- data/spec/lib/llt/helpers/query_methods_spec.rb +67 -0
- data/spec/lib/llt/helpers/roman_numerals_spec.rb +41 -0
- data/spec/lib/llt/helpers/terminology_spec.rb +165 -0
- data/spec/lib/llt/helpers/transformer_spec.rb +49 -0
- data/spec/spec_helper.rb +22 -0
- metadata +182 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2736c0ba15940c0b17d92e1750ec75ac57ed15fd
|
4
|
+
data.tar.gz: a466c7dceddeda33740ac15b1b2609ee7584b1a9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a353333c065c7353cec40220247feff8efba3a7ddacdbc39a09de8a1a46cedb29d0b049ca47cc3190e4f6669c1769a255d41a9d144b21eacea250797e300e033
|
7
|
+
data.tar.gz: ebe615476bf16ca0de06213dd4fb3b1eece1d8bf7c1af58aa2115478b70e0f525834539061328e126ecad95cabae4f7cb5868fddf60191ef79d6e73c96d0464d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 LFDM
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# LLT::Helpers
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'llt-helpers'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install llt-helpers
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/llt/helpers.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "llt/helpers/version"
|
2
|
+
require "llt/helpers/terminology"
|
3
|
+
require "llt/helpers/configuration"
|
4
|
+
require "llt/helpers/constantize"
|
5
|
+
require "llt/helpers/equality"
|
6
|
+
require "llt/helpers/functions"
|
7
|
+
require "llt/helpers/initialize"
|
8
|
+
require "llt/helpers/metrical"
|
9
|
+
require "llt/helpers/normalizer"
|
10
|
+
require "llt/helpers/pluralize"
|
11
|
+
require "llt/helpers/positions"
|
12
|
+
require "llt/helpers/primitive_cache"
|
13
|
+
require "llt/helpers/query_methods"
|
14
|
+
require "llt/helpers/roman_numerals"
|
15
|
+
require "llt/helpers/transformer"
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module LLT
|
2
|
+
module Helpers
|
3
|
+
# currently not used, implemented slightly differently in LLT::Service class
|
4
|
+
module Configuration
|
5
|
+
def self.included(obj)
|
6
|
+
obj.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
def configure(options = {})
|
10
|
+
# It might appeal here to refactor this to us merge.
|
11
|
+
# Don't do it: we don't want everything that might be present in options,
|
12
|
+
# only what we use in the configuration. Cf. specs.
|
13
|
+
configuration.each do |key, (val, _)|
|
14
|
+
val = options[key] || val
|
15
|
+
instance_variable_set("@#{key}", val)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def configuration
|
20
|
+
self.class.configuration
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
def configuration
|
25
|
+
@configuration ||= {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def reload!
|
29
|
+
configuration.each do |_, arr|
|
30
|
+
arr[0] = arr[1].call
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def method_missing(meth, *args, &blk)
|
35
|
+
if meth.to_s.match(/^uses_(.*)/)
|
36
|
+
configuration[$1.to_sym] = [blk.call, blk]
|
37
|
+
else
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module LLT
|
2
|
+
module Helpers
|
3
|
+
module Constantize
|
4
|
+
def constant_by_type(type = @type, prefix: "", suffix: "", namespace: LLT)
|
5
|
+
|
6
|
+
raise ArgumentError.new("type cannot be nil") if type.nil?
|
7
|
+
|
8
|
+
t = begin
|
9
|
+
Terminology.send(type, :full)
|
10
|
+
rescue
|
11
|
+
type
|
12
|
+
end
|
13
|
+
scope = namespace || self.class
|
14
|
+
arg = "#{classified(prefix)}#{classified(t)}#{classified(suffix)}"
|
15
|
+
scope.const_get(arg)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def classified(arg)
|
21
|
+
arg.to_s.split("_").map(&:capitalize).join
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module LLT
|
2
|
+
module Helpers
|
3
|
+
module Equality
|
4
|
+
|
5
|
+
# Intended to be uses as Class Extension.
|
6
|
+
# Responds to class methods in form of
|
7
|
+
# .equality_of_***_defined_by and takes several
|
8
|
+
# params, which define equality operators for the
|
9
|
+
# classes instance.
|
10
|
+
# These instances then respond to #same_***_as?(object).
|
11
|
+
def method_missing(meth, *args, &blk)
|
12
|
+
if meth.to_s.match(/^equality_of_(.*)_defined_by/)
|
13
|
+
equality_definition = "equality_definition_for_#{$1}"
|
14
|
+
define_method(equality_definition) do
|
15
|
+
args.map { |arg| send(arg) }
|
16
|
+
end
|
17
|
+
|
18
|
+
equality_comparator = "same_#{$1}_as?"
|
19
|
+
define_method(equality_comparator) do |other|
|
20
|
+
send(equality_definition) == other.send(equality_definition)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module LLT
|
2
|
+
module Helpers
|
3
|
+
module Functions
|
4
|
+
|
5
|
+
# Objects that use this module must implement #functions,
|
6
|
+
# which shall respond to #include?
|
7
|
+
def has_function?(function)
|
8
|
+
functions.include?(function)
|
9
|
+
end
|
10
|
+
|
11
|
+
def has_not_function? function
|
12
|
+
! has_function?(function)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Shortcut methods
|
16
|
+
def has_f?(function)
|
17
|
+
# Do not alias or delegate.
|
18
|
+
#
|
19
|
+
# It's (slightly) faster that way and this method will usually
|
20
|
+
# get lots of calls.
|
21
|
+
functions.include?(function)
|
22
|
+
end
|
23
|
+
alias :has_not_f? :has_not_function?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module LLT
|
2
|
+
module Helpers
|
3
|
+
module Initialize
|
4
|
+
|
5
|
+
# Maps Hash keys to instance_variables
|
6
|
+
#
|
7
|
+
# Recommended usage is to implement #init_keys as an Array of Symbols
|
8
|
+
# Example:
|
9
|
+
# def init_keys
|
10
|
+
# %i{ type stem inflection_class }
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# This will set @type, @stem and @inflection_class with their
|
14
|
+
# corresponding values.
|
15
|
+
# Keys not defined in init_keys or as param are untouched.
|
16
|
+
def extract_args!(args, keys = init_keys)
|
17
|
+
keys.each do |var_name|
|
18
|
+
instance_variable_set("@#{var_name}", args[var_name])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def extract_normalized_args!(args, keys = init_keys)
|
23
|
+
args = Helpers::Normalizer.normalize_args(args)
|
24
|
+
extract_args!(args, keys)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module LLT
|
2
|
+
module Helpers
|
3
|
+
module Metrical
|
4
|
+
QUANTIFIED_CHARS = {
|
5
|
+
'a' => ['ă', 'ā'],
|
6
|
+
'e' => ['ĕ', 'ē'],
|
7
|
+
'i' => ['ĭ', 'ī'],
|
8
|
+
'o' => ['ŏ', 'ō'],
|
9
|
+
'u' => ['ŭ', 'ū'],
|
10
|
+
'y' => ['ў', 'ȳ'],
|
11
|
+
}
|
12
|
+
QUANTIFIED_CHARS_REGEXP = /[#{QUANTIFIED_CHARS.values.flatten.join}]/
|
13
|
+
QUANTIFIED_CHARS_SUB_MAP = QUANTIFIED_CHARS.each_with_object({}) do |(norm, quant), h|
|
14
|
+
quant.each { |quantified| h[quantified] = norm }
|
15
|
+
end
|
16
|
+
|
17
|
+
def evaluate_metrical_presence(string)
|
18
|
+
@metrical = string && string.match(QUANTIFIED_CHARS_REGEXP)
|
19
|
+
end
|
20
|
+
|
21
|
+
def metrical?
|
22
|
+
@metrical
|
23
|
+
end
|
24
|
+
|
25
|
+
# without meter
|
26
|
+
def wo_meter(string)
|
27
|
+
string.gsub(QUANTIFIED_CHARS_REGEXP, QUANTIFIED_CHARS_SUB_MAP)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module LLT
|
2
|
+
module Helpers
|
3
|
+
module Normalizer
|
4
|
+
def normalize_args(args)
|
5
|
+
args.each_with_object({}) do |(orig_k, v), hash|
|
6
|
+
if orig_k == :options
|
7
|
+
hash[orig_k] = normalize_args(v)
|
8
|
+
else
|
9
|
+
norm_k = terminology.key_term_for(orig_k)
|
10
|
+
if norm_k
|
11
|
+
hash[norm_k] = terminology.value_term_for(norm_k, v)
|
12
|
+
else
|
13
|
+
key = (orig_k == 'stem' ? orig_k.to_sym : orig_k)
|
14
|
+
hash[key] = v
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def terminology
|
21
|
+
Terminology
|
22
|
+
end
|
23
|
+
alias :t :terminology
|
24
|
+
|
25
|
+
extend self
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module LLT
|
2
|
+
module Helpers
|
3
|
+
module Pluralize
|
4
|
+
def pluralize(count, sg, pl = nil)
|
5
|
+
if count == 1
|
6
|
+
sg
|
7
|
+
else
|
8
|
+
pl || build_plural(sg)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def build_plural(sg)
|
15
|
+
sg = sg.clone
|
16
|
+
case sg
|
17
|
+
when /y$/ then sg.chop << "ies"
|
18
|
+
else sg << "s"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module LLT
|
2
|
+
module Helpers
|
3
|
+
module Positions
|
4
|
+
# Adds Comparable-like methods and more to an object, that holds an instance variable @position
|
5
|
+
# While the Comparable module itself could be included, defining these methods manually comes with
|
6
|
+
# a significant performance gain.
|
7
|
+
|
8
|
+
def === other
|
9
|
+
@position == other.position
|
10
|
+
end
|
11
|
+
|
12
|
+
def < other
|
13
|
+
@position < other.position
|
14
|
+
end
|
15
|
+
|
16
|
+
def > other
|
17
|
+
@position > other.position
|
18
|
+
end
|
19
|
+
|
20
|
+
def >= other
|
21
|
+
@position >= other.position
|
22
|
+
end
|
23
|
+
|
24
|
+
def <= other
|
25
|
+
@position >= other.position
|
26
|
+
end
|
27
|
+
|
28
|
+
def <=> other
|
29
|
+
@position <=> other.position
|
30
|
+
end
|
31
|
+
|
32
|
+
def - other # used by Rating
|
33
|
+
@position - other.position
|
34
|
+
end
|
35
|
+
|
36
|
+
def surrounding
|
37
|
+
[@position - 1, @position + 1]
|
38
|
+
end
|
39
|
+
|
40
|
+
def distance_to(other, absolute = false)
|
41
|
+
d = other - self
|
42
|
+
absolute ? d.abs : d
|
43
|
+
end
|
44
|
+
|
45
|
+
def nearest_in(arr)
|
46
|
+
arr.sort_by { |el| distance_to(el, true) }.first
|
47
|
+
end
|
48
|
+
|
49
|
+
def in_front_of?(other, steps = 1)
|
50
|
+
(other - self).between?(1, steps + 1)
|
51
|
+
end
|
52
|
+
|
53
|
+
def next_in(arr, &blk)
|
54
|
+
arr.next_elem(self, &blk)
|
55
|
+
end
|
56
|
+
|
57
|
+
def prev_in(arr, &blk)
|
58
|
+
arr.prev_elem(self, &blk)
|
59
|
+
end
|
60
|
+
|
61
|
+
def at_sentence_start(sos)
|
62
|
+
@position == sos || @position == sos + 1
|
63
|
+
end
|
64
|
+
|
65
|
+
def in_front_of_any?(arr, steps = 1)
|
66
|
+
arr.any? { |e| self.in_front_of?(e, steps) }
|
67
|
+
end
|
68
|
+
|
69
|
+
def behind_any?(arr, steps = 1)
|
70
|
+
arr.any? { |e| self.behind?(e, steps) }
|
71
|
+
end
|
72
|
+
|
73
|
+
def behind?(other, steps = 1)
|
74
|
+
(self - other).between?(1, steps + 1) # (self - other) < steps + 1 not valid => true for negatives!
|
75
|
+
end
|
76
|
+
|
77
|
+
def close_to?(other, steps = 1)
|
78
|
+
(self - other).abs < steps + 1
|
79
|
+
end
|
80
|
+
|
81
|
+
def between? a, b
|
82
|
+
@position.between?(a.position, b.position)
|
83
|
+
end
|
84
|
+
|
85
|
+
def range_with(other, to_range = false)
|
86
|
+
a, b = [@position, other.position].sort
|
87
|
+
|
88
|
+
range = ((a + 1)...b)
|
89
|
+
to_range ? range : range.to_a
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|