Lingua-EN-Inflexion

 view release on metacpan or  search on metacpan

lib/Lingua/EN/Inflexion/Term.pm  view on Meta::CPAN

                         )
                     :   $encase->( $term,
                               $noun_inflexion_of{nominative}{lc $term}{singular}[$person]
                            // $noun_inflexion_of{objective }{lc $term}{singular}[$person]
                            // $noun_inflexion_of{possessive}{lc $term}{singular}[$person]
                            // $noun_inflexion_of{reflexive }{lc $term}{singular}[$person]
                            // Lingua::EN::Inflexion::Nouns::convert_to_singular( $term, $person )
                         );
}


sub plural {
    my $self   = shift;
    my $person = shift // 0;

    my $term = $term_of{$self};

    # Prepositions imply objective or possessive (or dative)...
    my $preposition = $term =~ s{ \A ( \s* $PREP_PAT \s+ ) }{}xi ? $1 : q{};

    return
          $preposition ?   $preposition
                         . $encase->( $term,
                                $noun_inflexion_of{objective }{lc $term}{plural}[$person]
                             // $noun_inflexion_of{possessive}{lc $term}{plural}[$person]
                             // $noun_inflexion_of{reflexive }{lc $term}{plural}[$person]
                             // $noun_inflexion_of{nominative}{lc $term}{plural}[$person]
                             // Lingua::EN::Inflexion::Nouns::convert_to_modern_plural($term,$person)
                           )
                       :   $encase->( $term,
                                $noun_inflexion_of{nominative}{lc $term}{plural}[$person]
                             // $noun_inflexion_of{objective }{lc $term}{plural}[$person]
                             // $noun_inflexion_of{possessive}{lc $term}{plural}[$person]
                             // $noun_inflexion_of{reflexive }{lc $term}{plural}[$person]
                             // Lingua::EN::Inflexion::Nouns::convert_to_modern_plural($term,$person)
                           );
}


sub indef_article {
    my ($self) = @_;

    return Lingua::EN::Inflexion::Indefinite::select_indefinite_article($self->singular);
}

sub indefinite {
    my ($self, $count) = @_;
    $count //= 1;

    if ($count == 1 ) {
        return Lingua::EN::Inflexion::Indefinite::prepend_indefinite_article($self->singular);
    }
    else {
        return "$count " . $self->plural;
    }
}


# Conversions to ordinal and cardinal numbers (with module loaded on demand)...
my $num2word = sub {
    state $load = require Lingua::EN::Nums2Words && Lingua::EN::Nums2Words::set_case('lower');
    Lingua::EN::Nums2Words::num2word(@_);
};

my $num2word_short_ordinal = sub {
    state $load = require Lingua::EN::Nums2Words && Lingua::EN::Nums2Words::set_case('lower');
    Lingua::EN::Nums2Words::num2word_short_ordinal(@_);
};

my $num2word_ordinal = sub {
    state $load = require Lingua::EN::Nums2Words && Lingua::EN::Nums2Words::set_case('lower');
    Lingua::EN::Nums2Words::num2word_ordinal(@_);
};

# These words may need an "and" before them...
my $LAST_WORD = qr{
       one    | two    | three | four | five | six | seven  | eight | nine | ten
     | eleven | twelve | teen  | ty
     | first  | second | third | [rfxnhe]th
}x;

# These words may need an "and" after them...
my $POWER_WORD = qr{
    hundred | thousand | \S+illion
}x;

sub cardinal {
    my $value = $term_of{ shift() };
    my $max_trans = shift();

    # Load the necessary module, and compensate for its persnicketiness...
    state $load = require Lingua::EN::Words2Nums;
    local $SIG{__WARN__} = sub{};

    # Make sure we have a number...
    $value = Lingua::EN::Words2Nums::words2nums($value) // $value;

    # If it's above threshold, return it as a number...
    return $value
        if defined $max_trans && $value >= $max_trans;

    # Otherwise, convert it to words...
    my $words = $num2word->($value);

    # Correct for proper English pronunciation...
    if ($value > 100) {
        $words =~ s{ ($POWER_WORD) \s+ (\S*$LAST_WORD) \b } {$1 and $2}gx;
        $words =~ s{    (?<! and ) \s+ (\S*$LAST_WORD) $  } { and $1}gx;
        $words =~ s{ ^ ([^,]+),([^,]+) $ }                  {$1$2}x;
    }

    return $words;
}

sub ordinal {
    my $value = $term_of{ shift() };
    my $max_trans = shift();

    # Load the necessary module, and compensate for its persnicketiness...
    state $load = require Lingua::EN::Words2Nums;
    local $SIG{__WARN__} = sub{};

    # Make sure we have a number...
    $value = Lingua::EN::Words2Nums::words2nums($value) // $value;

    # If it's above threshold, return it as a number...
    return $num2word_short_ordinal->($value)
        if defined $max_trans && $value >= $max_trans;

    # Otherwise, convert it to words...
    my $words = $num2word_ordinal->( $value );

    # Correct for proper English pronunciation...
    if ($value > 100) {
        $words =~ s{ ($POWER_WORD) \s+ (\S*$LAST_WORD) \b } {$1 and $2}gx;
        $words =~ s{    (?<! and ) \s+ (\S*$LAST_WORD) $  } { and $1}gx;
        $words =~ s{ ^ ([^,]+),([^,]+) $ }                  {$1$2}x;
    }

    return $words;
}


# Return a classical version of the term...
sub classical  { Lingua::EN::Inflexion::Noun::Classical->new(shift) }


package Lingua::EN::Inflexion::Noun::Classical;
our @ISA = 'Lingua::EN::Inflexion::Noun';

# Inside-out ctor expects a base-class object to clone...
sub new {
    my ($class, $orig_object) = @_;

    my $new_object = bless do{ \my $scalar }, $class;

    # Special case of "them" (because "it" -> "they" and "it -> "them" are ambiguous)...
    $term_of{$new_object}
         = $term_of{$orig_object} eq 'them' ? $term_of{$orig_object}
         :                                    $orig_object->singular;

    # Otherwise...

    return $new_object;
}

# Already a classical noun, so this is now idempotent...
sub classical { return shift }

# Classical plurals are different...
sub plural {
    my $self   = shift;
    my $person = shift // 0;

    my $term = $term_of{$self};

    # Prepositions imply objective or possessive (or dative)...
    my $preposition = $term =~ s{ \A ( \s* $PREP_PAT \s+ ) }{}xi ? $1 : q{};




( run in 2.491 seconds using v1.01-cache-2.11-cpan-364913b4093 )