class Identifiers::ISBN
Constants
- ISBN_10_REGEXP
- ISBN_13_REGEXP
- ISBN_A_REGEXP
Public Class Methods
digits_of(isbn)
click to toggle source
# File lib/identifiers/isbn.rb, line 103 def self.digits_of(isbn) isbn.to_s.each_char.map { |char| char == 'X' ? 10 : Integer(char) }.to_enum end
extract(str)
click to toggle source
# File lib/identifiers/isbn.rb, line 43 def self.extract(str) extract_isbn_as(str) + extract_thirteen_digit_isbns(str) + extract_ten_digit_isbns(str) end
extract_isbn_as(str)
click to toggle source
# File lib/identifiers/isbn.rb, line 47 def self.extract_isbn_as(str) extract_thirteen_digit_isbns(str.to_s.scan(ISBN_A_REGEXP).join("\n").tr('/.', '')) end
extract_ten_digit_isbns(str)
click to toggle source
# File lib/identifiers/isbn.rb, line 60 def self.extract_ten_digit_isbns(str) str .to_s .scan(ISBN_10_REGEXP) .select { |isbn, hyphen| !hyphen || isbn.count(hyphen) == 3 } .map { |isbn, hyphen| isbn.delete(hyphen.to_s) } .select { |isbn| valid_isbn_10?(isbn) } .map { |isbn| isbn.chop! isbn.prepend('978') isbn << isbn_13_check_digit(isbn).to_s isbn } end
extract_thirteen_digit_isbns(str)
click to toggle source
# File lib/identifiers/isbn.rb, line 51 def self.extract_thirteen_digit_isbns(str) str .to_s .scan(ISBN_13_REGEXP) .select { |isbn, hyphen| !hyphen || isbn.count(hyphen) == 4 } .map { |isbn, hyphen| isbn.delete(hyphen.to_s) } .select { |isbn| valid_isbn_13?(isbn) } end
isbn_13_check_digit(isbn)
click to toggle source
# File lib/identifiers/isbn.rb, line 76 def self.isbn_13_check_digit(isbn) sum = digits_of(isbn).zip([1, 3].cycle).map { |digit, weight| digit * weight }.reduce(:+) check_digit = 10 - (sum % 10) if check_digit == 10 0 else check_digit end end
valid_isbn_10?(isbn)
click to toggle source
# File lib/identifiers/isbn.rb, line 95 def self.valid_isbn_10?(isbn) return false unless String(isbn).length == 10 && isbn =~ ISBN_10_REGEXP result = digits_of(isbn).with_index.map { |digit, weight| digit * weight.succ }.reduce(:+) (result % 11).zero? end
valid_isbn_13?(isbn)
click to toggle source
# File lib/identifiers/isbn.rb, line 87 def self.valid_isbn_13?(isbn) return false unless String(isbn).length == 13 && isbn =~ ISBN_13_REGEXP result = digits_of(isbn).zip([1, 3].cycle).map { |digit, weight| digit * weight }.reduce(:+) (result % 10).zero? end