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

#isbnObject

Returns a normalized ISBN form



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

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

#isbn10Object

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



33
34
35
36
37
38
39
# File 'lib/lisbn/lisbn.rb', line 33

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

  isbn[3..-2] + isbn_10_checksum
end

#isbn13Object

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



43
44
45
46
47
48
# File 'lib/lisbn/lisbn.rb', line 43

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

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

#isbn_10_checksumObject



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/lisbn/lisbn.rb', line 96

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

  sum = base[0].to_i * 10 +
        base[1].to_i *  9 +
        base[2].to_i *  8 +
        base[3].to_i *  7 +
        base[4].to_i *  6 +
        base[5].to_i *  5 +
        base[6].to_i *  4 +
        base[7].to_i *  3 +
        base[8].to_i *  2

  remainder = sum % 11

  case remainder
    when 0
      "0"
    when 1
      "X"
    else
      (11 - remainder).to_s
  end
end

#isbn_13_checksumObject



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/lisbn/lisbn.rb', line 121

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

  sum = (
          base[1].to_i +
          base[3].to_i +
          base[5].to_i +
          base[7].to_i +
          base[9].to_i +
          base[11].to_i
        ) * 3 +
        base[0].to_i +
        base[2].to_i +
        base[4].to_i +
        base[6].to_i +
        base[8].to_i +
        base[10].to_i +
        base[12].to_i

  (10 - sum % 10).to_s[-1]
end

#isbn_with_dashObject



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

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

#parts(parts = 5) ⇒ Object

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

- GS1 prefix (only for ISBN-13)
- Group identifier
- Prefix/publisher code
- Item number
- Check digit

Returns nil if the ISBN is not valid. Returns nil if parts argument is 4 but ISBN-10 does not exist Returns nil if the group and prefix cannot be identified.

Raises:

  • (ArgumentError)


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/lisbn/lisbn.rb', line 61

def parts(parts = 5)
  raise ArgumentError, "Parts must be either 4 or 5." unless parts == 4 || parts == 5
  return unless isbn13
  return if parts == 4 && !isbn10

  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])

  if parts == 4
    [group[3..-1], prefix, isbn10[(group[3..-1].length + prefix.length)..-2], isbn10[-1..-1]]
  else
    [group[0..2], group[3..-1], prefix, isbn13[(group.length + prefix.length)..-2], isbn13[-1..-1]]
  end
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