<commit_before><?php

namespace Nicebooks\Isbn;

use Nicebooks\Isbn\Exception\IsbnException;
use Nicebooks\Isbn\Internal\RangeService;
use Nicebooks\Isbn\Internal\RangeInfo;

/**
 * Represents a valid ISBN number. This class is immutable.
 */
class Isbn
{
    /**
     * @var string
     */
    private $isbn;

    /**
     * @var bool
     */
    private $is13;

    /**
     * @var RangeInfo|null
     */
    private $rangeInfo;

    /**
     * @param string $isbn The unformatted ISBN number, validated.
     * @param bool   $is13 Whether this is an ISBN-13.
     */
    private function __construct($isbn, $is13)
    {
        $this->isbn = $isbn;
        $this->is13 = $is13;

        $this->rangeInfo = RangeService::getRangeInfo($isbn);
    }

    /**
     * @param string $isbn
     *
     * @return Isbn
     *
     * @throws Exception\InvalidIsbnException
     */
    public static function of($isbn)
    {
        $isbn = (string) $isbn;

        if (preg_match(Internal\Regexp::ASCII, $isbn) === 0) {
            throw Exception\InvalidIsbnException::forIsbn($isbn);
        }

        $isbn = preg_replace(Internal\Regexp::NON_ALNUM, '', $isbn);

        if (preg_match(Internal\Regexp::ISBN13, $isbn) === 1) {
            if (! Internal\CheckDigit::validateCheckDigit13($isbn)) {
                throw Exception\InvalidIsbnException::forIsbn($isbn);
            }

            return new Isbn($isbn, true);
        }

        $isbn = strtoupper($isbn);

        if (preg_match(Internal\Regexp::ISBN10, $isbn) === 1) {
            if (! Internal\CheckDigit::validateCheckDigit10($isbn)) {
                throw Exception\InvalidIsbnException::forIsbn($isbn);
            }

            return new Isbn($isbn, false);
        }

        throw Exception\InvalidIsbnException::forIsbn($isbn);
    }

    /**
     * @return bool
     */
    public function is10()
    {
        return ! $this->is13;
    }

    /**
     * @return bool
     */
    public function is13()
    {
        return $this->is13;
    }

    /**
     * @return bool
     */
    public function isConvertibleTo10()
    {
        if ($this->is13) {
            return substr($this->isbn, 0, 3) === '978';
        }

        return true;
    }

    /**
     * Returns a copy of this Isbn, converted to ISBN-10.
     *
     * @return Isbn The ISBN-10.
     *
     * @throws Exception\IsbnNotConvertibleException If this is an ISBN-13 not starting with 978.
     */
    public function to10()
    {
        if (! $this->is13) {
            return $this;
        }

        return new Isbn(Internal\Converter::convertIsbn13to10($this->isbn), false);
    }

    /**
     * Returns a copy of this Isbn, converted to ISBN-13.
     *
     * @return Isbn The ISBN-13.
     */
    public function to13()
    {
        if ($this->is13) {
            return $this;
        }

        return new Isbn(Internal\Converter::convertIsbn10to13($this->isbn), true);
    }

    /**
     * Returns whether this ISBN is in a recognized group.
     *
     * If this method returns true, the following methods will not throw an exception:
     *
     * - getGroupIdentifier()
     * - getGroupName()
     *
     * @return bool
     */
    public function isValidGroup()
    {
        return $this->rangeInfo !== null;
    }

    /**
     * Returns whether this ISBN is in a recognized range.
     *
     * If this method returns false, we are unable to split the ISBN into parts, and format it with hyphens.
     * It would mean that either the ISBN number is wrong, or this version of the library is compiled against
     * an outdated data file from ISBN International.
     *
     * Note that this method returns true only means that the ISBN number is *potentially* valid,
     * but it is by no means a way to check if the ISBN number has been *assigned* yet.
     *
     * If this method returns true, format() will return a hyphenated result,
     * and the following methods will not throw an exception:
     *
     * - getGroupIdentifier()
     * - getGroupName()
     * - getPublisherIdentifier()
     * - getTitleIdentifier()
     * - getParts()
     *
     * @return bool
     */
    public function isValidRange()
    {
        return $this->rangeInfo !== null && $this->rangeInfo->parts !== null;
    }<commit_msg>Minor doc changes<commit_after><?php

namespace Nicebooks\Isbn;

use Nicebooks\Isbn\Exception\IsbnException;
use Nicebooks\Isbn\Internal\RangeService;
use Nicebooks\Isbn\Internal\RangeInfo;

/**
 * Represents a valid ISBN number. This class is immutable.
 */
class Isbn
{
    /**
     * @var string
     */
    private $isbn;

    /**
     * @var bool
     */
    private $is13;

    /**
     * @var RangeInfo|null
     */
    private $rangeInfo;

    /**
     * @param string $isbn The unformatted ISBN number, validated.
     * @param bool   $is13 Whether this is an ISBN-13.
     */
    private function __construct($isbn, $is13)
    {
        $this->isbn = $isbn;
        $this->is13 = $is13;

        $this->rangeInfo = RangeService::getRangeInfo($isbn);
    }

    /**
     * @param string $isbn
     *
     * @return Isbn
     *
     * @throws Exception\InvalidIsbnException
     */
    public static function of($isbn)
    {
        $isbn = (string) $isbn;

        if (preg_match(Internal\Regexp::ASCII, $isbn) === 0) {
            throw Exception\InvalidIsbnException::forIsbn($isbn);
        }

        $isbn = preg_replace(Internal\Regexp::NON_ALNUM, '', $isbn);

        if (preg_match(Internal\Regexp::ISBN13, $isbn) === 1) {
            if (! Internal\CheckDigit::validateCheckDigit13($isbn)) {
                throw Exception\InvalidIsbnException::forIsbn($isbn);
            }

            return new Isbn($isbn, true);
        }

        $isbn = strtoupper($isbn);

        if (preg_match(Internal\Regexp::ISBN10, $isbn) === 1) {
            if (! Internal\CheckDigit::validateCheckDigit10($isbn)) {
                throw Exception\InvalidIsbnException::forIsbn($isbn);
            }

            return new Isbn($isbn, false);
        }

        throw Exception\InvalidIsbnException::forIsbn($isbn);
    }

    /**
     * @return bool
     */
    public function is10()
    {
        return ! $this->is13;
    }

    /**
     * @return bool
     */
    public function is13()
    {
        return $this->is13;
    }

    /**
     * @return bool
     */
    public function isConvertibleTo10()
    {
        if ($this->is13) {
            return substr($this->isbn, 0, 3) === '978';
        }

        return true;
    }

    /**
     * Returns a copy of this Isbn, converted to ISBN-10.
     *
     * @return Isbn The ISBN-10.
     *
     * @throws Exception\IsbnNotConvertibleException If this is an ISBN-13 not starting with 978.
     */
    public function to10()
    {
        if (! $this->is13) {
            return $this;
        }

        return new Isbn(Internal\Converter::convertIsbn13to10($this->isbn), false);
    }

    /**
     * Returns a copy of this Isbn, converted to ISBN-13.
     *
     * @return Isbn The ISBN-13.
     */
    public function to13()
    {
        if ($this->is13) {
            return $this;
        }

        return new Isbn(Internal\Converter::convertIsbn10to13($this->isbn), true);
    }

    /**
     * Returns whether this ISBN is in a recognized group.
     *
     * If this method returns true, the following methods will not throw an exception:
     *
     * - getGroupIdentifier()
     * - getGroupName()
     *
     * @return bool
     */
    public function isValidGroup()
    {
        return $this->rangeInfo !== null;
    }

    /**
     * Returns whether this ISBN is in a recognized range.
     *
     * If this method returns false, we are unable to split the ISBN into parts, and format it with hyphens.
     * This would mean that either the ISBN number is wrong, or this version of the library is compiled against
     * an outdated data file from ISBN International.
     *
     * Note that this method returning true only means that the ISBN number is *potentially* valid,
     * but does not indicate in any way whether the ISBN number has been *assigned* to a book yet.
     *
     * If this method returns true, format() will return a hyphenated result,
     * and the following methods will not throw an exception:
     *
     * - getGroupIdentifier()
     * - getGroupName()
     * - getPublisherIdentifier()
     * - getTitleIdentifier()
     * - getParts()
     *
     * @return bool
     */
    public function isValidRange()
    {
        return $this->rangeInfo !== null && $this->rangeInfo->parts !== null;
    }
{'fraction_non_alphanumeric': 0.11808547804821241, 'fraction_numerical': 0.016070804704786303, 'mean_word_length': 1.9892098851374869, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4957709', 'n_tokens_mistral': 2692, 'n_tokens_neox': 2582, 'n_words': 702}