Class: Lisbn

Inherits:
String
  • Object
show all
Extended by:
CacheMethod
Defined in:
lib/lisbn/lisbn.rb,
lib/lisbn/ranges.rb,
lib/lisbn/cache_method.rb

Defined Under Namespace

Modules: CacheMethod, Ranges

Instance Method Summary collapse

Methods included from CacheMethod

cache_method

Instance Method Details

#isbn ⇒ Object

Returns a normalized ISBN form



3
4
5
# File 'lib/lisbn/lisbn.rb', line 3

def isbn
  upcase.gsub(/[^0-9X]/, '')
end

#isbn10 ⇒ Object

Returns a valid ISBN in ISBN-10 format. Returns nil if the ISBN is invalid or incapable of conversion to ISBN-10.



31
32
33
34
35
36
37
# File 'lib/lisbn/lisbn.rb', line 31

def isbn10
  return unless valid?
  return isbn if isbn.length == 10
  return unless isbn[0..2] == "978"

  isbn[3..-2] + isbn_10_checksum
end

#isbn13 ⇒ Object

Returns a valid ISBN in ISBN-13 format. Returns nil if the ISBN is invalid.



41
42
43
44
45
46
# File 'lib/lisbn/lisbn.rb', line 41

def isbn13
  return unless valid?
  return isbn if isbn.length == 13

  '978' + isbn[0..-2] + isbn_13_checksum
end

#isbn_10_checksum ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/lisbn/lisbn.rb', line 86

def isbn_10_checksum
  base = isbn.length == 13 ? isbn[3..-2] : isbn[0..-2]

  products = base.each_char.each_with_index.map do |chr, i|
    chr.to_i * (10 - i)
  end

  remainder = products.inject(0) {|m, v| m + v} % 11
  case remainder
    when 0
      0
    when 1
      'X'
    else
      11 - remainder
  end.to_s
end

#isbn_13_checksum ⇒ Object



104
105
106
107
108
109
110
111
112
113
# File 'lib/lisbn/lisbn.rb', line 104

def isbn_13_checksum
  base = (isbn.length == 13 ? '' : '978') + isbn[0..-2]

  products = base.each_char.each_with_index.map do |chr, i|
    chr.to_i * (i % 2 == 0 ? 1 : 3)
  end

  remainder = products.inject(0) {|m, v| m + v} % 10
  (remainder == 0 ? 0 : 10 - remainder).to_s
end

#isbn_with_dash ⇒ Object



19
20
21
22
23
24
25
26
27
# File 'lib/lisbn/lisbn.rb', line 19

def isbn_with_dash
  if valid_isbn_13? && parts
    parts.join("-")
  elsif isbn.length > 3
    isbn[0..-2] + "-" + isbn[-1]
  else
    isbn
  end
end

#parts ⇒ Object

Returns an Array with the 'parts' of the ISBN-13 in left-to-right order. The parts of an ISBN are as follows:

- GS1 prefix
- Group identifier
- Prefix/publisher code
- Item number
- Check digit

Returns nil if the ISBN is not valid. Returns nil if the group and prefix cannot be identified.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/lisbn/lisbn.rb', line 58

def parts
  return unless isbn13

  group = prefix = nil

  RANGES.each_pair do |g, prefixes|
    next unless isbn13.match("^#{g}")
    group = g

    pre_loc = group.length
    prefixes.each do |p|
      number = isbn13.slice(pre_loc, p[:length]).to_i
      next unless p[:range].include?(number)

      prefix = p.merge(:number => number)
      break
    end

    break
  end

  # In the unlikely event we can't categorize it...
  return unless group && prefix

  prefix = sprintf("%0#{prefix[:length]}d", prefix[:number])
  [group[0..2], group[3..-1], prefix, isbn13[(group.length + prefix.length)..-2], isbn13[-1..-1]]
end

#valid? ⇒ Boolean

Returns true if the ISBN is valid, false otherwise.

Returns:

  • (Boolean)


8
9
10
11
12
13
14
15
16
17
# File 'lib/lisbn/lisbn.rb', line 8

def valid?
  case isbn.length
    when 10
      valid_isbn_10?
    when 13
      valid_isbn_13?
    else
      false
  end
end