llt-helpers 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +6 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +8 -0
  7. data/lib/llt/helpers.rb +15 -0
  8. data/lib/llt/helpers/configuration.rb +44 -0
  9. data/lib/llt/helpers/constantize.rb +25 -0
  10. data/lib/llt/helpers/equality.rb +28 -0
  11. data/lib/llt/helpers/functions.rb +26 -0
  12. data/lib/llt/helpers/initialize.rb +28 -0
  13. data/lib/llt/helpers/metrical.rb +31 -0
  14. data/lib/llt/helpers/normalizer.rb +28 -0
  15. data/lib/llt/helpers/pluralize.rb +23 -0
  16. data/lib/llt/helpers/positions.rb +93 -0
  17. data/lib/llt/helpers/primitive_cache.rb +37 -0
  18. data/lib/llt/helpers/query_methods.rb +30 -0
  19. data/lib/llt/helpers/roman_numerals.rb +50 -0
  20. data/lib/llt/helpers/terminology.rb +219 -0
  21. data/lib/llt/helpers/transformer.rb +33 -0
  22. data/lib/llt/helpers/version.rb +5 -0
  23. data/llt-helpers.gemspec +27 -0
  24. data/spec/lib/llt/helpers/configuration_spec.rb +77 -0
  25. data/spec/lib/llt/helpers/constantize_spec.rb +79 -0
  26. data/spec/lib/llt/helpers/equality_spec.rb +48 -0
  27. data/spec/lib/llt/helpers/functions_spec.rb +47 -0
  28. data/spec/lib/llt/helpers/initialize_spec.rb +50 -0
  29. data/spec/lib/llt/helpers/metrical_spec.rb +40 -0
  30. data/spec/lib/llt/helpers/normalizer_spec.rb +57 -0
  31. data/spec/lib/llt/helpers/pluralize_spec.rb +38 -0
  32. data/spec/lib/llt/helpers/positions_spec.rb +108 -0
  33. data/spec/lib/llt/helpers/primitive_cache_spec.rb +65 -0
  34. data/spec/lib/llt/helpers/query_methods_spec.rb +67 -0
  35. data/spec/lib/llt/helpers/roman_numerals_spec.rb +41 -0
  36. data/spec/lib/llt/helpers/terminology_spec.rb +165 -0
  37. data/spec/lib/llt/helpers/transformer_spec.rb +49 -0
  38. data/spec/spec_helper.rb +22 -0
  39. metadata +182 -0
@@ -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
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in llt-helpers.gemspec
4
+ gemspec
5
+ gem 'coveralls', require: false
6
+ gem 'llt-constants', git: 'git@github.com:latin-language-toolkit/llt-constants.git'
@@ -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.
@@ -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
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.rspec_opts = '-f d --color --tty'
6
+ end
7
+
8
+ task :default => :spec
@@ -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