llt-helpers 0.0.4
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 +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
|