Vebjorn Ljosa

CL-ISBN

Introduction

CL-ISBN is a Common Lisp library for parsing, validating, and hyphenating International Standard Book Numbers (ISBNs). ISBNs consist of 10 or 13 digits. (For 10-digit ISBNs, the last "digit" may also be the letter X; in this document, X is considered a digit when appropriate.)

When printing an ISBN, hyphens should be inserted between the structural parts of the ISBN. For instance, the ISBN 0201175894 should be printed as 0-201-17589-4, separating area 0 (the English-language region) from registrant 201 (Addison Wesley), publication 19589 ("Object-Oriented Programming in Common Lisp" by Sonya Keene), and check digit 4. Correct hyphenation is not difficult, but a separate library is warranted because various tables must be consulted. The tables are maintained by the International ISBN Agency and the national ISBN agencies, and grow over time as new groups (countries) are added and as the national ISBN agencies add new ranges of registrant (publisher) numbers to their numbering schemes.

Ten-digit ISBNs have been used since 1970. Starting in 2007, 13-digit ISBNs will come into use. CL-ISBN support both types, and can convert between them. The 13-digit ISBNs are a subset of EANs, so the library can be used to convert between 10-digit ISBNs and the 13-digit "Bookland" EAN barcodes found on the back of books.

Limitations

PARSE-ISBN does not accept the five-digit add-on code to EAN-13.

Status

CL-ISBN is a new library, so the interface may change in later versions. There are some open questions about the interface that can hopefully be answered after a few users have had some experience with the library:

  1. Should the five-digit add on code be supported, or at least accepted and ignored by PARSE-ISBN?

  2. Should check-isbn verify not only the syntactical validity of the ISBN, but also that the group and registrant ranges exist in the internal tables? This would help catch more data entry errors, but would cause problems whenever new groups or registrant ranges are added, as ISBNs in these ranges would not be accepted into a system using CL-ISBN. (This is obviously a more serious problem that not being able to format the ISBN correctly.)

  3. Should format-isbn signal a different condition than ERROR when a range cannot be found?

  4. Should parse-isbn be more permissible, and not require a certain number of hyphens or spaces, or that they appear on the interior of the string?

  5. Should there be an interface to the internals of the conditions signaled by check-isbn and parse-isbn so that the offending string or ISBN can be retrieved?

License

CL-ISBN is covered by a BSD-style license (see license.txt). This manual is in the public domain.

Download

The latest version is 0.2, and can be downloaded from http://www.ljosa.com/~ljosa/software/cl-isbn/download/cl-isbn-0.2.tar.gz. Older versions can be downloaded from http://www.ljosa.com/~ljosa/software/cl-isbn/download/.

The individual source code files are available here, in case you would like to take a look at the code before downloading.

The ISBN, ISBN-10, and ISBN-13 classes

The ISBN class is abstract, i.e., it should never be instantiated. ISBN-10 and ISBN-13 instances are internal representations of 10-digit and 13-digit ISBNs, respectively.

ISBNs are instantiated using make-instance and the initarg :digits. Examples:

    (make-instance 'isbn-10 :digits "0201175894")
    => #<ISBN-10 "0201175894">

    (make-instance 'isbn-13 :digits "9780201175899")
    => #<ISBN-13 "9780201175899">

The argument to :digits should be a string of 10 or 13 digits, as appropriate for the class being instantiated. However, the argument is not being checked for validity at the time of instantiation. If you do not trust that your digits constitute a valid ISBN, call check-isbn.

make-instance should only be used to construct an ISBN from a string of digits from an internal source, such as a database. In order to construct an ISBN from user input or other source that may include hyphens or spaces, use parse-isbn.

The library will not mutate the string given as argument to :digits.

isbn-digits                                          (accessor)

The accessor ISBN-DIGITS can be used to access the digits after instantiation.

Converting between ISBN-10 and ISBN-13

make-instance can be used with the :isbn initarg to convert 10-digit ISBNs to 13-digits ISBNs and vice-versa. Examples:

    (make-instance 'isbn-10 :digits "0201175894")
    => #<ISBN-10 "0201175894">
    (make-instance 'isbn-13 :isbn *)
    => #<ISBN-13 "9780201175899">
    (make-instance 'isbn-10 :isbn *)
    => #<ISBN-10 "0201175894">

The same mechanism can be used to copy an ISBN:

    (make-instance 'isbn-10 :digits "0201175894")
    => #<ISBN-10 "0201175894">
    (make-instance 'isbn-10 :isbn *)
    => #<ISBN-10 "0201175894">
    (eq * **)
    => NIL
    (eq (isbn-digits ***) (isbn-digits **))
    => NIL

Checking for well-formedness and correct check digit

check-isbn (isbn &key ignore-check-digit)      generic function

Arguments:

isbn
-- an instance of class ISBN
ignore-check-digit
-- a boolean

Returns: T
Signals: isbn-parse-error or isbn-check-digit-error

The function check-isbn first checks that the ISBN is valid, i.e., that it consists of the correct number of digits of the appropriate type (digits 0 through 9, except that the last digit of a 10-digit ISBN can be #\X or #\x). If this is not correct is signals an isbn-parse-error. If ignore-check-digit is true, check-isbn returns T at this point. Otherwise, the function checks that the check digit is correct. If so, it returns T; if not, it signals isbn-check-digit-error.

Errors

isbn-parse-error                                      condition

Direct subtype of error.

isbn-check-digit-error                                condition

Direct subtype of isbn-parse-error.

Parsing ISBNs from strings

parse-isbn (string &key (invalid-check-digit :error))  function

Arguments:

string
-- an expternal representation of an ISBN, with or without hypens or spaces
invalid-check-digit
-- a symbol (either :error or :correct)

Returns: an instance of class isbn
Signals: isbn-parse-error or isbn-check-digit-error

parse-isbn decides whether STRING looks like a 10-digit or a 13-digit ISBN, parses it, and checks the resulting ISBN for validity before returning.

The string must contain either no hyphens or spaces, or the number of hyphens or spaces appropriate for the type of ISBN (3 for a 10-digit ISBN, 4 for a 13-digit ISBN). There cannot be a mixture of hyphens and spaces, and the hyphens or spaces must be interior to the string.

parse-isbn does not require that the hyphens be in the right place. For instance, "0-2011-7589-4" will be parsed just fine, even though the correct hyphentation is "0-201-17589-4".

The function signals isbn-parse-error if STRING does not look like an ISBN.

If INVALID-CHECK-DIGIT is :error, the function signals isbn-check-digit-error if the check digit is incorrect. In INVALID-CHECK-DIGIT is :correct, an incorrect check digit is silently corrected, and a valid ISBN returned.

The :correct argument to INVALID-CHECK-DIGIT is useful only for testing (to avoid the trouble of coming up with correct input) and for publishers wishing to construct an ISBN for a new book.

Formatting ISBNs

format-isbn (isbn)			      generic function

Arguments:

isbn
-- an instance of class ISBN

Returns: A string containing the formatted ISBN
Signals: ERROR

FORMAT-ISBN formats the ISBN by inserting hyphens in the appropriate places and returning the result as a string of length 13 or 17, as appropriate for the type of ISBN.

FORMAT-ISBN signals an error if the information in the internal tables is not sufficient for deciding how to hyphenate an ISBN. If this occurs for an ISBN that appears on a book (as opposed to an ISBN you just made up), it is a bug.

Accessing individual structural elements

The following five functions return the various structural elements of an ISBN. ISBN-PREFIX is only defined on instances of ISBN-13.

Just like FORMAT-ISBN, some of these function (namely, ISBN-GROUP, ISBN-REGISTRANT, and ISBN-PUBLICATION) signal an error if the information in the internal tables is not sufficient for deciding how to hyphenate an ISBN.

isbn-prefix (isbn-13)                          generic function

Returns a string of length 3 containing the prefix of the ISBN. Only defined for 13-digit ISBNs (i.e., instances of ISBN-13).

isbn-group (isbn)			      generic function

Returns a string containing the number of the group (language area, country, region) of the ISBN. For 10-digit ISBNs and for 13-digit ISBNs with prefix 978, the length of the string may vary from 1 to 5.

isbn-registrant (isbn)			       generic function

Returns a string containing the number of the registrant (publisher) of the ISBN. For 10-digit ISBNs and for 13-digit ISBNs with prefix 978, the length of the string may vary from 1 to 7.

isbn-publication (isbn)			       generic function

Returns a string containing the number of the publication (title) of the ISBN. For 10-digit ISBNs and for 13-digit ISBNs with prefix 978, the length of the string may vary from 1 to 7.

isbn-check-digit (isbn)			      generic function

Returns a string of length 1 containing the check digit of the ISBN. For 10-digit ISBNs, the check digit can be "0" through "9", as well as "X" and "x". For 13-digit ISBNs, the check digit can only be "0" through "9".

References

ISBN Users' Manual (ISBN-10)
http://www.isbn-international.org/en/userman/download/ISBNmanual.pdf

ISBN Users' Manual (ISBN-13)
http://www.isbn-international.org/en/download/2005%20ISBN%20Users%27%20Manual%20International%20Edition.pdf

Complete list of group identifiers
http://www.isbn-international.org/en/identifiers/allidentifiers.html

List of prefix ranges
http://www.isbn-international.org/en/identifiers/List-of-Ranges.pdf

International ISBN Agency
http://www.isbn-international.org/


Last updated: 2005-07-15