taxamatch_rb 0.9.10 → 1.0.0

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.
data/CHANGELOG CHANGED
@@ -1,11 +1,14 @@
1
+ 1.0.0 - fixed a parsing problem with infraspecies without string,
2
+ upgraded version to 1 because the signature of the gem did stabilized
3
+
1
4
  0.9.8 - fixed a parsing problem with species nodes without name
2
5
 
3
6
  0.9.4 - updated parser (to 1.0.16), updated code to ruby 1.9.3
4
7
 
5
- 0.9.3 - Taxamatch::Normalizer substitutes multiplication sign to 'x'
8
+ 0.9.3 - Taxamatch::Normalizer substitutes multiplication sign to 'x'
6
9
  (lowcase) instead of '?'
7
10
 
8
- 0.9.2 - Taxamatch::Normalizer.normalize always returns only ASCII
11
+ 0.9.2 - Taxamatch::Normalizer.normalize always returns only ASCII
9
12
  characters, all utf-8 characters unknown to normalizer are becoming '?'
10
13
 
11
14
  0.9.1 - updated gems
data/Gemfile CHANGED
@@ -1,21 +1,19 @@
1
- source "http://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
  require 'yaml'
3
- # YAML::ENGINE.yamler= 'syck'
4
3
 
5
- gem "biodiversity19","~> 2.1"
6
- gem "damerau-levenshtein", ">= 0.5.4"
4
+ gem 'biodiversity','~> 3.0.1'
5
+ gem 'damerau-levenshtein', '~> 0.5.4'
7
6
  gem 'json', '~> 1.7.7'
8
7
 
9
-
10
- group :development do
11
- gem "rake"
12
- gem "rake-compiler"
13
- gem "rspec"
14
- gem "cucumber", ">= 0"
15
- gem "bundler", "~> 1.3"
16
- gem "jeweler", "~> 1.6.0"
17
- gem "debugger"
18
- gem "ruby-prof"
19
- gem "shoulda"
20
- gem "mocha"
8
+ group :test do
9
+ gem 'rake', '~> 10.0'
10
+ gem 'rake-compiler', '~> 0.8'
11
+ gem 'rspec', '~> 2.13'
12
+ gem 'cucumber', '~> 1.3'
13
+ gem 'bundler', '~> 1.3'
14
+ gem 'jeweler', '~> 1.8'
15
+ gem 'debugger', '~> 1.5'
16
+ gem 'ruby-prof', '~> 0.13'
17
+ gem 'shoulda', '~> 3.5'
18
+ gem 'mocha', '~> 0.13'
21
19
  end
@@ -1,10 +1,10 @@
1
1
  GEM
2
- remote: http://rubygems.org/
2
+ remote: https://rubygems.org/
3
3
  specs:
4
4
  activesupport (3.2.13)
5
5
  i18n (= 0.6.1)
6
6
  multi_json (~> 1.0)
7
- biodiversity19 (2.1.0)
7
+ biodiversity (3.0.1)
8
8
  parallel
9
9
  parallel (~> 0.6)
10
10
  rake (~> 10.0)
@@ -18,11 +18,7 @@ GEM
18
18
  diff-lcs (>= 1.1.3)
19
19
  gherkin (~> 2.12.0)
20
20
  multi_json (~> 1.3)
21
- damerau-levenshtein (1.0.0)
22
- bundler (~> 1)
23
- jeweler (~> 1)
24
- rake (~> 10)
25
- rake-compiler (~> 0.8)
21
+ damerau-levenshtein (0.5.4)
26
22
  debugger (1.5.0)
27
23
  columnize (>= 0.3.1)
28
24
  debugger-linecache (~> 1.2.0)
@@ -34,10 +30,11 @@ GEM
34
30
  multi_json (~> 1.3)
35
31
  git (1.2.5)
36
32
  i18n (0.6.1)
37
- jeweler (1.6.4)
33
+ jeweler (1.8.4)
38
34
  bundler (~> 1.0)
39
35
  git (>= 1.2.5)
40
36
  rake
37
+ rdoc
41
38
  json (1.7.7)
42
39
  metaclass (0.0.1)
43
40
  mocha (0.13.3)
@@ -48,6 +45,8 @@ GEM
48
45
  rake (10.0.4)
49
46
  rake-compiler (0.8.3)
50
47
  rake
48
+ rdoc (4.0.1)
49
+ json (~> 1.4)
51
50
  rspec (2.13.0)
52
51
  rspec-core (~> 2.13.0)
53
52
  rspec-expectations (~> 2.13.0)
@@ -72,16 +71,16 @@ PLATFORMS
72
71
  ruby
73
72
 
74
73
  DEPENDENCIES
75
- biodiversity19 (~> 2.1)
74
+ biodiversity (~> 3.0.1)
76
75
  bundler (~> 1.3)
77
- cucumber
78
- damerau-levenshtein (>= 0.5.4)
79
- debugger
80
- jeweler (~> 1.6.0)
76
+ cucumber (~> 1.3)
77
+ damerau-levenshtein (~> 0.5.4)
78
+ debugger (~> 1.5)
79
+ jeweler (~> 1.8)
81
80
  json (~> 1.7.7)
82
- mocha
83
- rake
84
- rake-compiler
85
- rspec
86
- ruby-prof
87
- shoulda
81
+ mocha (~> 0.13)
82
+ rake (~> 10.0)
83
+ rake-compiler (~> 0.8)
84
+ rspec (~> 2.13)
85
+ ruby-prof (~> 0.13)
86
+ shoulda (~> 3.5)
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Dmitry Mozzherin
1
+ Copyright (c) 2009-2013 Marine Biological Laboratory
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,8 +1,16 @@
1
- = taxamatch_rb
1
+ Taxamatch_Rb
2
+ ============
2
3
 
3
- Taxamatch_Rb is a ruby implementation of Taxamatch algorithms developed by Tony Rees: http://www.cmar.csiro.au/datacentre/taxamatch.htm
4
+ [![Gem Version][1]][2]
5
+ [![Continuous Integration Status][3]][4]
6
+ [![Dependency Status][5]][6]
4
7
 
5
- The purpose of Taxamatch gem is to facilitate fuzzy comparison of two scientific name renderings to find out if they actually point to the same scientific name.
8
+ Taxamatch_Rb is a ruby implementation of Taxamatch algorithms
9
+ [developed by Tony Rees][7]:
10
+
11
+ The purpose of Taxamatch gem is to facilitate fuzzy comparison of
12
+ two scientific name renderings to find out if they actually point to
13
+ the same scientific name.
6
14
 
7
15
  require 'taxamatch_rb'
8
16
  tm = Taxamatch::Base.new
@@ -12,11 +20,13 @@ The purpose of Taxamatch gem is to facilitate fuzzy comparison of two scientific
12
20
 
13
21
  Taxamatch_Rb is compatible with ruby versions 1.9.1 and higher
14
22
 
15
- == Installation
23
+ Installation
24
+ ------------
16
25
 
17
26
  sudo gem install taxamatch_rb
18
27
 
19
- == Usage
28
+ Usage
29
+ -----
20
30
 
21
31
  require 'taxamatch_rb'
22
32
 
@@ -51,6 +61,15 @@ Taxamatch_Rb is compatible with ruby versions 1.9.1 and higher
51
61
 
52
62
  You can find more examples in spec section of the code
53
63
 
54
- == Copyright
64
+ Copyright
65
+ ---------
66
+
67
+ Copyright (c) 2009-2013 Marine Biological Laboratory. See LICENSE for details.
55
68
 
56
- Copyright (c) 2009 Dmitry Mozzherin. See LICENSE for details.
69
+ [1]: https://badge.fury.io/rb/taxamatch_rb.png
70
+ [2]: http://badge.fury.io/rb/taxamatch_rb
71
+ [3]: https://secure.travis-ci.org/GlobalNamesArchitecture/taxamatch_rb.png
72
+ [4]: http://travis-ci.org/GlobalNamesArchitecture/taxamatch_rb
73
+ [5]: https://gemnasium.com/GlobalNamesArchitecture/taxamatch_rb.png
74
+ [6]: https://gemnasium.com/GlobalNamesArchitecture/taxamatch_rb
75
+ [7]: http://www.cmar.csiro.au/datacentre/taxamatch.htm
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ begin
5
5
  Bundler.setup(:default, :development)
6
6
  rescue Bundler::BundlerError => e
7
7
  $stderr.puts e.message
8
- $stderr.puts "Run `bundle install` to install missing gems"
8
+ $stderr.puts 'Run `bundle install` to install missing gems'
9
9
  exit e.status_code
10
10
  end
11
11
 
@@ -14,21 +14,23 @@ require 'rake'
14
14
  begin
15
15
  require 'jeweler'
16
16
  Jeweler::Tasks.new do |gem|
17
- gem.name = "taxamatch_rb"
17
+ gem.name = 'taxamatch_rb'
18
18
  gem.summary = 'Implementation of Tony Rees Taxamatch algorithms'
19
- gem.description = 'This gem implements algorithm for fuzzy matching scientific names developed by Tony Rees'
20
- gem.email = "dmozzherin@eol.org"
21
- gem.homepage = "http://github.com/GlobalNamesArchitecture/taxamatch_rb"
22
- gem.authors = ["Dmitry Mozzherin"]
23
- gem.files = FileList["[A-Z]*", "*.gemspec", "{bin,generators,lib,spec}/**/*"]
19
+ gem.description = 'This gem implements algorithm ' +
20
+ 'for fuzzy matching scientific names developed by Tony Rees'
21
+ gem.email = 'dmozzherin@gmail.com'
22
+ gem.homepage = 'http://github.com/GlobalNamesArchitecture/taxamatch_rb'
23
+ gem.authors = ['Dmitry Mozzherin']
24
+ gem.files = FileList['[A-Z]*',
25
+ '*.gemspec', '{bin,generators,lib,spec}/**/*']
24
26
  gem.files -= FileList['lib/**/*.bundle', 'lib/**/*.dll', 'lib/**/*.so']
25
27
  gem.files += FileList['ext/**/*.c']
26
28
  gem.extensions = FileList['ext/**/extconf.rb']
27
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
28
29
  end
29
30
 
30
31
  rescue LoadError
31
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
32
+ puts 'Jeweler (or a dependency) not available.' +
33
+ ' Install it with: sudo gem install jeweler'
32
34
  end
33
35
 
34
36
  require 'rspec/core'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.10
1
+ 1.0.0
@@ -1,6 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  $:.unshift(File.dirname(__FILE__)) unless
3
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+ $:.include?(File.dirname(__FILE__)) ||
4
+ $:.include?(File.expand_path(File.dirname(__FILE__)))
4
5
  # $:.unshift('taxamatch_rb')
5
6
  require 'damerau-levenshtein'
6
7
  require 'taxamatch_rb/atomizer'
@@ -8,8 +9,9 @@ require 'taxamatch_rb/normalizer'
8
9
  require 'taxamatch_rb/phonetizer'
9
10
  require 'taxamatch_rb/authmatch'
10
11
 
11
- raise "IMPORTANT: Parsley-store gem requires ruby >= 1.9.1" if RUBY_VERSION < "1.9.1"
12
- $KCODE='u' if RUBY_VERSION.split('.')[1].to_i < 9
12
+ if RUBY_VERSION < '1.9.1'
13
+ raise 'IMPORTANT: Parsley-store gem requires ruby >= 1.9.1'
14
+ end
13
15
 
14
16
  module Taxamatch
15
17
 
@@ -21,7 +23,8 @@ module Taxamatch
21
23
  end
22
24
 
23
25
 
24
- #takes two scientific names and returns true if names match and false if they don't
26
+ # takes two scientific names and returns true
27
+ # if names match and false if they don't
25
28
  def taxamatch(str1, str2, return_boolean = true)
26
29
  preparsed_1 = @parser.parse(str1)
27
30
  preparsed_2 = @parser.parse(str2)
@@ -29,14 +32,19 @@ module Taxamatch
29
32
  return_boolean ? (!!match && match['match']) : match
30
33
  end
31
34
 
32
- #takes two hashes of parsed scientific names, analyses them and returns back
33
- #this function is useful when species strings are preparsed.
35
+ # takes two hashes of parsed scientific names, analyses them and
36
+ # returns back this function is useful when species strings are preparsed.
34
37
  def taxamatch_preparsed(preparsed_1, preparsed_2)
35
38
  result = nil
36
- result = match_uninomial(preparsed_1, preparsed_2) if preparsed_1[:uninomial] && preparsed_2[:uninomial]
37
- result = match_multinomial(preparsed_1, preparsed_2) if preparsed_1[:genus] && preparsed_2[:genus]
39
+ if preparsed_1[:uninomial] && preparsed_2[:uninomial]
40
+ result = match_uninomial(preparsed_1, preparsed_2)
41
+ end
42
+ if preparsed_1[:genus] && preparsed_2[:genus]
43
+ result = match_multinomial(preparsed_1, preparsed_2)
44
+ end
38
45
  if result && result['match']
39
- result['match'] = match_authors(preparsed_1, preparsed_2) == -1 ? false : true
46
+ result['match'] = match_authors(preparsed_1, preparsed_2) == -1 ?
47
+ false : true
40
48
  end
41
49
  return result
42
50
  end
@@ -48,65 +56,89 @@ module Taxamatch
48
56
  def match_multinomial(preparsed_1, preparsed_2)
49
57
  gen_match = match_genera(preparsed_1[:genus], preparsed_2[:genus])
50
58
  sp_match = match_species(preparsed_1[:species], preparsed_2[:species])
51
- total_length = preparsed_1[:genus][:string].size + preparsed_2[:genus][:string].size + preparsed_1[:species][:string].size + preparsed_2[:species][:string].size
59
+ total_length = preparsed_1[:genus][:string].size +
60
+ preparsed_2[:genus][:string].size +
61
+ preparsed_1[:species][:string].size +
62
+ preparsed_2[:species][:string].size
52
63
  if preparsed_1[:infraspecies] && preparsed_2[:infraspecies]
53
- infrasp_match = match_species(preparsed_1[:infraspecies][0], preparsed_2[:infraspecies][0])
54
- total_length += preparsed_1[:infraspecies][0][:string].size + preparsed_2[:infraspecies][0][:string].size
64
+ infrasp_match = match_species(preparsed_1[:infraspecies][0],
65
+ preparsed_2[:infraspecies][0])
66
+ total_length += preparsed_1[:infraspecies][0][:string].size +
67
+ preparsed_2[:infraspecies][0][:string].size
55
68
  match_hash = match_matches(gen_match, sp_match, infrasp_match)
56
- elsif (preparsed_1[:infraspecies] && !preparsed_2[:infraspecies]) || (!preparsed_1[:infraspecies] && preparsed_2[:infraspecies])
57
- match_hash = { 'match' => false, 'edit_distance' => 5, 'phonetic_match' => false }
58
- total_length += preparsed_1[:infraspecies] ? preparsed_1[:infraspecies][0][:string].size : preparsed_2[:infraspecies][0][:string].size
69
+ elsif (preparsed_1[:infraspecies] && !preparsed_2[:infraspecies]) ||
70
+ (!preparsed_1[:infraspecies] && preparsed_2[:infraspecies])
71
+ match_hash = { 'match' => false,
72
+ 'edit_distance' => 5,
73
+ 'phonetic_match' => false }
74
+ total_length += preparsed_1[:infraspecies] ?
75
+ preparsed_1[:infraspecies][0][:string].size :
76
+ preparsed_2[:infraspecies][0][:string].size
59
77
  else
60
78
  match_hash = match_matches(gen_match, sp_match)
61
79
  end
62
- match_hash.merge({'score' => (1 - match_hash['edit_distance']/(total_length/2))})
80
+ match_hash.merge({ 'score' =>
81
+ (1 - match_hash['edit_distance']/(total_length/2)) })
63
82
  match_hash
64
83
  end
65
84
 
66
85
  def match_genera(genus1, genus2, opts = {})
67
86
  genus1_length = genus1[:normalized].size
68
87
  genus2_length = genus2[:normalized].size
69
- opts = {:with_phonetic_match => true}.merge(opts)
88
+ opts = { with_phonetic_match: true }.merge(opts)
70
89
  min_length = [genus1_length, genus2_length].min
71
- unless opts[:with_phonetic_match]
72
- genus1[:phonetized] = "A"
73
- genus2[:phonetized] = "B"
90
+ unless opts[:with_phonetic_match]
91
+ genus1[:phonetized] = 'A'
92
+ genus2[:phonetized] = 'B'
74
93
  end
75
94
  match = false
76
- ed = @dlm.distance(genus1[:normalized], genus2[:normalized], 1, 3) #TODO put block = 2
77
- return {'edit_distance' => ed, 'phonetic_match' => false, 'match' => false} if ed/min_length.to_f > 0.2
78
- return {'edit_distance' => ed, 'phonetic_match' => true, 'match' => true} if genus1[:phonetized] == genus2[:phonetized]
79
-
80
- match = true if ed <= 3 && (min_length > ed * 2) && (ed < 2 || genus1[0] == genus2[0])
81
- {'edit_distance' => ed, 'match' => match, 'phonetic_match' => false}
95
+ ed = @dlm.distance(genus1[:normalized],
96
+ genus2[:normalized], 1, 3) #TODO put block = 2
97
+ return { 'edit_distance' => ed,
98
+ 'phonetic_match' => false,
99
+ 'match' => false } if ed/min_length.to_f > 0.2
100
+ return { 'edit_distance' => ed,
101
+ 'phonetic_match' => true,
102
+ 'match' => true } if genus1[:phonetized] == genus2[:phonetized]
103
+
104
+ match = true if ed <= 3 && (min_length > ed * 2) &&
105
+ (ed < 2 || genus1[0] == genus2[0])
106
+ { 'edit_distance' => ed, 'match' => match, 'phonetic_match' => false }
82
107
  end
83
108
 
84
109
  def match_species(sp1, sp2, opts = {})
85
110
  sp1_length = sp1[:normalized].size
86
111
  sp2_length = sp2[:normalized].size
87
- opts = {:with_phonetic_match => true}.merge(opts)
112
+ opts = { with_phonetic_match: true }.merge(opts)
88
113
  min_length = [sp1_length, sp2_length].min
89
114
  unless opts[:with_phonetic_match]
90
- sp1[:phonetized] = "A"
91
- sp2[:phonetized] = "B"
92
- end
115
+ sp1[:phonetized] = 'A'
116
+ sp2[:phonetized] = 'B'
117
+ end
93
118
  sp1[:phonetized] = Taxamatch::Phonetizer.normalize_ending sp1[:phonetized]
94
119
  sp2[:phonetized] = Taxamatch::Phonetizer.normalize_ending sp2[:phonetized]
95
120
  match = false
96
- ed = @dlm.distance(sp1[:normalized], sp2[:normalized], 1, 4) #TODO put block 4
97
- return {'edit_distance' => ed, 'phonetic_match' => false, 'match' => false} if ed/min_length.to_f > 0.3334
98
- #puts 's: %s, %s, %s' % [sp1[:normalized], sp2[:normalized], ed]
99
- return {'edit_distance' => ed, 'phonetic_match' => true, 'match' => true} if sp1[:phonetized] == sp2[:phonetized]
100
-
101
- match = true if ed <= 4 && (min_length >= ed * 2) && (ed < 2 || sp1[:normalized][0] == sp2[:normalized][0]) && (ed < 4 || sp1[:normalized][0...3] == sp2[:normalized][0...3])
102
- { 'edit_distance' => ed, 'match' => match, 'phonetic_match' => false}
121
+ ed = @dlm.distance(sp1[:normalized],
122
+ sp2[:normalized], 1, 4) #TODO put block 4
123
+ return { 'edit_distance' => ed,
124
+ 'phonetic_match' => false,
125
+ 'match' => false } if ed/min_length.to_f > 0.3334
126
+ return {'edit_distance' => ed,
127
+ 'phonetic_match' => true,
128
+ 'match' => true} if sp1[:phonetized] == sp2[:phonetized]
129
+
130
+ match = true if ed <= 4 &&
131
+ (min_length >= ed * 2) &&
132
+ (ed < 2 || sp1[:normalized][0] == sp2[:normalized][0]) &&
133
+ (ed < 4 || sp1[:normalized][0...3] == sp2[:normalized][0...3])
134
+ { 'edit_distance' => ed, 'match' => match, 'phonetic_match' => false }
103
135
  end
104
136
 
105
137
  def match_authors(preparsed_1, preparsed_2)
106
- p1 = { :normalized_authors => [], :years => [] }
107
- p2 = { :normalized_authors => [], :years => [] }
138
+ p1 = { normalized_authors: [], years: [] }
139
+ p2 = { normalized_authors: [], years: [] }
108
140
  if preparsed_1[:infraspecies] || preparsed_2[:infraspecies]
109
- p1 = preparsed_1[:infraspecies].last if preparsed_1[:infraspecies]
141
+ p1 = preparsed_1[:infraspecies].last if preparsed_1[:infraspecies]
110
142
  p2 = preparsed_2[:infraspecies].last if preparsed_2[:infraspecies]
111
143
  elsif preparsed_1[:species] || preparsed_2[:species]
112
144
  p1 = preparsed_1[:species] if preparsed_1[:species]
@@ -119,7 +151,7 @@ module Taxamatch
119
151
  au2 = p2[:normalized_authors]
120
152
  yr1 = p1[:years]
121
153
  yr2 = p2[:years]
122
- return 0 if au1.empty? || au2.empty?
154
+ return 0 if au1.empty? || au2.empty?
123
155
  score = Taxamatch::Authmatch.authmatch(au1, au2, yr1, yr2)
124
156
  score == 0 ? -1 : 1
125
157
  end
@@ -132,12 +164,13 @@ module Taxamatch
132
164
  match['phonetic_match'] &&= infraspecies_match['phonetic_match']
133
165
  end
134
166
  match['edit_distance'] += genus_match['edit_distance']
135
- match['match'] = false if match['edit_distance'] > (infraspecies_match ? 6 : 4)
167
+ if match['edit_distance'] > (infraspecies_match ? 6 : 4)
168
+ match['match'] = false
169
+ end
136
170
  match['match'] &&= genus_match['match']
137
171
  match['phonetic_match'] &&= genus_match['phonetic_match']
138
172
  match
139
173
  end
140
174
 
141
175
  end
142
-
143
176
  end
@@ -9,12 +9,12 @@ module Taxamatch
9
9
  @parsed_raw = nil
10
10
  @res = {}
11
11
  end
12
-
12
+
13
13
  def parse(name)
14
14
  @parsed_raw = @parser.parse(name)[:scientificName]
15
15
  organize_results(@parsed_raw)
16
16
  end
17
-
17
+
18
18
  def parsed_raw
19
19
  return @parsed_raw
20
20
  end
@@ -29,11 +29,13 @@ module Taxamatch
29
29
  process_node(:genus, d[:genus])
30
30
  process_node(:species, d[:species], true)
31
31
  process_infraspecies(d[:infraspecies])
32
- @res[:all_authors] = @res[:all_authors].uniq.map {|a| Taxamatch::Normalizer.normalize(a)}
32
+ @res[:all_authors] = @res[:all_authors].uniq.map do |a|
33
+ Taxamatch::Normalizer.normalize(a)
34
+ end
33
35
  @res[:all_years].uniq!
34
36
  @res.keys.size > 2 ? @res : nil
35
37
  end
36
-
38
+
37
39
  private
38
40
 
39
41
  def process_node(name, node, is_species = false)
@@ -41,14 +43,16 @@ module Taxamatch
41
43
  @res[name] = {}
42
44
  @res[name][:string] = node[:string]
43
45
  @res[name][:normalized] = Taxamatch::Normalizer.normalize(node[:string])
44
- @res[name][:phonetized] = Taxamatch::Phonetizer.near_match(node[:string], is_species)
46
+ @res[name][:phonetized] =
47
+ Taxamatch::Phonetizer.near_match(node[:string], is_species)
45
48
  get_authors_years(node, @res[name])
46
49
  end
47
-
50
+
48
51
  def process_infraspecies(node)
49
52
  return unless node
50
53
  @res[:infraspecies] = []
51
54
  node.each do |infr|
55
+ next unless infr[:string]
52
56
  hsh = {}
53
57
  hsh[:string] = infr[:string]
54
58
  hsh[:normalized] = Taxamatch::Normalizer.normalize(infr[:string])
@@ -57,7 +61,7 @@ module Taxamatch
57
61
  @res[:infraspecies] << hsh
58
62
  end
59
63
  end
60
-
64
+
61
65
  def get_authors_years(node, res)
62
66
  res[:authors] = []
63
67
  res[:years] = []
@@ -71,16 +75,21 @@ module Taxamatch
71
75
  if node[au][:exAuthorTeam]
72
76
  res[:authors] += node[au][:exAuthorTeam][:author]
73
77
  if node[au][:exAuthorTeam][:year]
74
- year = Taxamatch::Normalizer.normalize_year(node[au][:exAuthorTeam][:year])
78
+ year = node[au][:exAuthorTeam][:year]
79
+ year = Taxamatch::Normalizer.normalize_year(year)
75
80
  res[:years] << year if year
76
81
  end
77
82
  end
78
83
  end
79
84
  end
80
85
  res[:authors].uniq!
81
- res[:normalized_authors] = res[:authors].map {|a| Taxamatch::Normalizer.normalize_author(a)}
86
+ res[:normalized_authors] = res[:authors].map do |a|
87
+ Taxamatch::Normalizer.normalize_author(a)
88
+ end
82
89
  res[:years].uniq!
83
- @res[:all_authors] += res[:normalized_authors] if res[:normalized_authors].size > 0
90
+ if res[:normalized_authors].size > 0
91
+ @res[:all_authors] += res[:normalized_authors]
92
+ end
84
93
  @res[:all_years] += res[:years] if res[:years].size > 0
85
94
  end
86
95