module RuNumerals

Constants

ACCUSATIVE
ACCUSATIVE3
CASUS_STR
CENTGRAM

Грамматика слова “цент”

COMPOUNDS
DOLLARGRAM

Грамматика слова “доллар”

ENDING02678
ENDING1459
ENDING3
EUROCENTGRAM

Грамматика слова “евроцент”

EUROGRAM

Грамматика слова “евро”

EXTEND_MAP

RuNumerals contains methods that convert numeric values to russian numerals. The description and comments are in Russian as the use of this module implies the knowledge of the Russian language.

HOURGRAM
HUNDREDS
KOPGRAM

Грамматика слова “копейка”

MILLI_ENDING
MINGRAM
MONTAB
ONES
ONES1
ONES2
ORDINALS
ORDWORD
RUBGRAM

Грамматика слова “рубль”

SECGRAM
TEENCASES
TEENS
THOU_ENDING
TIES
TWENTIES
VERSION

RuNumerals version

WHOLEGRAM
YEARGRAM

Public Class Methods

extend(cls,*methods) click to toggle source

Добавляет метод или методы RuNumerals классу.

@param [Class] cls объект для преобразования
@param [Array] methods методы
   - :ru_numeral (+Symbol+) - добавить метод ru_numeral (только для +Integer+)
   - :ru_ordinal (+Symbol+) - добавить метод ru_ordinal (только для +Integer+)
   - :ru_date (+Symbol+) - добавить метод ru_date (только для +Time+)
   - :ru_time (+Symbol+) - добавить метод ru_time (только для +Time+)
   - :ru_fractional (+Symbol+) - добавить метод ru_fractional (только для +Float+ и +Rational+)
   - :ru_money (+Symbol+) - добавить метод ru_money (только для +Float+)
   - :ru_rubles (+Symbol+) - добавить метод ru_rubles (только для +Float+)
   - :ru_kopecks (+Symbol+) - добавить метод ru_kopecks (только для +Float+)
   - :ru_rubleskopecks (+Symbol+) - добавить метод ru_rubleskopecks (только для +Float+)
   - :ru_dollars (+Symbol+) - добавить метод ru_dollars (только для +Float+)
   - :ru_cents (+Symbol+) - добавить метод ru_cents (только для +Float+)
   - :ru_dollarscents (+Symbol+) - добавить метод ru_dollarscents (только для +Float+)
   - :ru_euros (+Symbol+) - добавить метод ru_euros (только для +Float+)
   - :ru_eurocents (+Symbol+) - добавить метод ru_eurocents (только для +Float+)
   - :ru_euroseurocents (+Symbol+) - добавить метод ru_euroseurocents (только для +Float+)

Если опции не указаны, то классу добавляются все подходящие функции.

@return [nil]
@raise [ArgumentError]
@example

   RuNumerals::extend(Integer)                 #=> nil
   1.ru_numeral                                #=> "один"
   1.ru_ordinal("д")                           #=> "первому"
   RuNumerals::extend(Float,:ru_rubleskopecks) #=> nil
   1.25.ru_rubleskopecks("и",:nospellkop)      #=> "один рубль 25 копеек"
# File lib/ru_numerals.rb, line 844
def extend(cls,*methods)
        if ( cls.class != Class ) then
                raise ArgumentError, %Q/Argument must be Class, current argument class is "#{cls.Class}, "/, caller
        end
        if not EXTEND_MAP.keys.include?(cls) then
                raise ArgumentError, %Q/Class "#{cls}" is not supported/, caller
        end
        if methods.nil? or methods.empty? then
                all_methods=true
        else
                all_methods=false
                methods.each do |i|
                        if not EXTEND_MAP[cls].include?(i) then
                                raise ArgumentError, %Q/Method "#{i}" is not supported for class "#{cls}"/, caller
                        end
                end
        end
        methods_to_ext= (all_methods ? EXTEND_MAP[cls] : methods)
        methods_to_ext.each do |i|
                case i 
                        when :ru_numeral then
                                cls.send(:define_method,i) do |gr_casus='и', grammar='мн', min_order=0|
                                        RuNumerals::ru_numeral(self, gr_casus, grammar, min_order)
                                end
                        when :ru_ordinal then
                                cls.send(:define_method,i) do |gr_casus='и', grammar='мн', plural=false|
                                        RuNumerals::ru_ordinal(self, gr_casus, grammar, plural)
                                end
                        when :ru_money then
                                cls.send(:define_method,i) do |gr_casus='и', r_gram=nil,k_gram=nil, **opts|
                                        RuNumerals::ru_money(self, gr_casus,r_gram,k_gram,opts)
                                end
                        when :ru_date then
                                cls.send(:define_method,i) do |gr_casus='и', **opts|
                                        RuNumerals::ru_date(self, gr_casus, opts)
                                end                                               
                        when :ru_time then
                                cls.send(:define_method,i) do |gr_casus='и', **opts|
                                        RuNumerals::ru_time(self, gr_casus, opts)
                                end                                               
                        when :ru_rubles then
                                cls.send(:define_method,i) do |gr_casus='и', **opts|
                                        RuNumerals::ru_rubles(self, gr_casus, opts)
                                end                                               
                        when :ru_kopecks then
                                cls.send(:define_method,i) do |gr_casus='и', **opts|
                                        RuNumerals::ru_kopecks(self, gr_casus, opts)
                                end                                               
                        when :ru_rubleskopecks then
                                cls.send(:define_method,i) do |gr_casus='и', **opts|
                                        RuNumerals::ru_rubleskopecks(self, gr_casus, opts)
                                end                                               
                        when :ru_dollars then
                                cls.send(:define_method,i) do |gr_casus='и', **opts|
                                        RuNumerals::ru_dollars(self, gr_casus, opts)
                                end                                               
                        when :ru_cents
                                cls.send(:define_method,i) do |gr_casus='и', **opts|
                                        RuNumerals::ru_cents(self, gr_casus, opts)
                                end                                               
                        when :ru_dollarscents then
                                cls.send(:define_method,i) do |gr_casus='и', **opts|
                                        RuNumerals::ru_dollarscents(self, gr_casus, opts)
                                end                                               
                        when :ru_euros then
                                cls.send(:define_method,i) do |gr_casus='и', **opts|
                                        RuNumerals::ru_euros(self, gr_casus, opts)
                                end                                               
                        when :ru_eurocents then
                                cls.send(:define_method,i) do |gr_casus='и', **opts|
                                        RuNumerals::ru_eurocents(self, gr_casus, opts)
                                end                                               
                        when :ru_euroseurocents then
                                cls.send(:define_method,i) do |gr_casus='и', **opts|
                                        RuNumerals::ru_euroseurocents(self, gr_casus, opts)
                                end                                               
                        when :ru_fractional then
                                cls.send(:define_method,i) do |gr_casus='и', grammar=nil, **opts|
                                        RuNumerals::ru_fractional(self, gr_casus, grammar, opts)
                                end                                               
                end
        end
        nil
end
ru_cents(n,gr_casus="и",**options) click to toggle source

Преобразует число в текстовое представление денежной суммы в центах (n*100)

@param [Integer,Float] n объект для преобразования
@param gr_casus [String] падеж числительного
@param [Hash] options опции
@option options [true,false] :spellkop (true) преобразовать в числительное число центов, значение выводится в формате "%02d"
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_cents(2123.29)           #=> "двести двенадцать тысяч триста двадцать девять центов"
   RuNumerals::ru_cents(3,"т",spellkop: false) #=> "300 центами"
# File lib/ru_numerals.rb, line 744
def ru_cents(n,gr_casus="и",**options)
        ru_money(n,gr_casus,nil,CENTGRAM,options)
end
ru_date(d, gr_casus="и", **options ) click to toggle source

Преобразует объект класса Time в текстовое представление даты

@param [Time] d объект для преобразования
@param gr_casus [String] падеж числительного
@param [Hash] options опции
@option options [true,false] :spelldd (true) преобразовать в числительное число месяца
@option options [true,false] :spellyy (true) преобразовать в числительное год
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_date(Time.now)                                 #=> "девятое ноября две тысячи шестнадцатого года"
   RuNumerals::ru_date(Time.now, "д",spellyy: false)             #=> "девятому ноября 2016 года"
   RuNumerals::ru_date(Time.now, spelldd: false, spellyy: false) #=> "9 ноября 2016 года"
# File lib/ru_numerals.rb, line 470
def ru_date(d, gr_casus="и", **options )
        if not d.kind_of?(Time) then
                raise ArgumentError, %Q/The argument must be Time class. Argument has class "#{d.class}", value "#{d}"/, caller
        end
        spelldd=true
        spellyy=true
        options.each do |k,v|
                case k
                        when :spelldd then spelldd=v
                        when :spellyy then spellyy=v
                        else raise ArgumentError, %Q/Invalid option key #{k} value "#{v}"/, caller
                end
        end
        if spelldd then
                day_part=ru_ordinal(d.day,gr_casus,"с")
        else
                day_part=d.day.to_s
        end
        day_part + " " + MONTAB[d.mon-1] + " " + (spellyy ? ru_ordinal(d.year,"р",YEARGRAM) : (d.year.to_s + " года"))
end
ru_dollars(n,gr_casus="и",**options) click to toggle source

Преобразует число в текстовое представление денежной суммы в долларах. Дробная часть отбрасываются.

@param [Integer,Float] n объект для преобразования
@param gr_casus [String] падеж числительного
@param [Hash] options опции
@option options [true,false] :spellrub (true) преобразовать в числительное число долларов
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_dollars(2123.29)           #=> "две тысячи сто двадцать три доллара"
   RuNumerals::ru_dollars(3,"т",spellrub: false) #=> "3 долларами"
# File lib/ru_numerals.rb, line 728
def ru_dollars(n,gr_casus="и",**options)
        ru_money(n,gr_casus,DOLLARGRAM,nil,options)
end
ru_dollarscents(n,gr_casus="и",**options) click to toggle source

Преобразует число в текстовое представление денежной суммы в долларах и центах

@param [Integer,Float] n объект для преобразования
@param gr_casus [String] падеж числительного
@param [Hash] options опции
@option options [true,false] :spellrub (true) преобразовать в числительное число долларов
@option options [true,false] :spellkop (true) преобразовать в числительное число центов, значение выводится в формате "%02d"
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_dollarscents(2123.29)           #=> "две тысячи сто двадцать три доллара двадцать девять центов"
   RuNumerals::ru_dollarscents(3,"т",spellkop: false) #=> "тремя долларами 00 центов"
# File lib/ru_numerals.rb, line 761
def ru_dollarscents(n,gr_casus="и",**options)
        ru_money(n,gr_casus,DOLLARGRAM,CENTGRAM,options)
end
ru_eurocents(n,gr_casus="и",**options) click to toggle source

Преобразует число в текстовое представление денежной суммы в евроцентах (n*100)

@param [Integer,Float] n объект для преобразования
@param gr_casus [String] падеж числительного
@param [Hash] options опции
@option options [true,false] :spellkop (true) преобразовать в числительное число евроцентов, значение выводится в формате "%02d"
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_eurocents(2123.29)           #=> "двести двенадцать тысяч триста двадцать девять евроцентов"
   RuNumerals::ru_eurocents(3,"т",spellkop: false) #=> "300 евроцентами"
# File lib/ru_numerals.rb, line 793
def ru_eurocents(n,gr_casus="и",**options)
        ru_money(n,gr_casus,nil,EUROCENTGRAM,options)
end
ru_euros(n,gr_casus="и",**options) click to toggle source

Преобразует число в текстовое представление денежной суммы в евро. Дробная часть отбрасываются.

@param [Integer,Float] n объект для преобразования
@param gr_casus [String] падеж числительного
@param [Hash] options опции
@option options [true,false] :spellrub (true) преобразовать в числительное число евро
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_euros(2123.29)           #=> "две тысячи сто двадцать три евро"
   RuNumerals::ru_euros(3,"т",spellrub: false) #=> "3 евро"
# File lib/ru_numerals.rb, line 777
def ru_euros(n,gr_casus="и",**options)
        ru_money(n,gr_casus,EUROGRAM,nil,options)
end
ru_euroseurocents(n,gr_casus="и",**options) click to toggle source

Преобразует число в текстовое представление денежной суммы в евро и евроцентах

@param [Integer,Float] n объект для преобразования
@param gr_casus [String] падеж числительного
@param [Hash] options опции
@option options [true,false] :spellrub (true) преобразовать в числительное число евро
@option options [true,false] :spellkop (true) преобразовать в числительное число евроцентов, значение выводится в формате "%02d"
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_euroseurocents(2123.29)           #=> "две тысячи сто двадцать три евро двадцать девять евроцентов"
   RuNumerals::ru_euroseurocents(3,"т",spellkop: false) #=> "тремя долларами 00 евроцентов"
# File lib/ru_numerals.rb, line 810
def ru_euroseurocents(n,gr_casus="и",**options)
        ru_money(n,gr_casus,EUROGRAM,EUROCENTGRAM,options)
end
ru_fractional(n,gr_casus="и",grammar=nil, **options) click to toggle source

Преобразует дробное число в его текстовое представление

@param [Rational, Float, Integer] n объект для преобразования
@param gr_casus [String] падеж числительного
@param grammar [String] грамматика
@param [Hash] options опции
@option options [true,false] :improper (false) не преобразовать в правильную дробь
@return [String]
@raise [ArgumentError]
Если знаменатель равен единице (аргумент типа +Integer+ как частный случай),
то результатом будет количественное числительное (будет осуществлен вызов ru_numeral)

@example

   RuNumerals::ru_fractional(Rational(8,7))                   #=> "одна целая одна седьмая"
   RuNumerals::ru_fractional(Rational(8,7),"",improper: true) #=> "восемь седьмых"
   RuNumerals::ru_fractional(Rational(8,7),improper: true)    #=> "восемь седьмых"
   RuNumerals::ru_fractional(Rational(6,2),"т")               #=> "тремя"
   RuNumerals::ru_fractional(1001.02)                         #=> "одна тысяча одна целая две сотых"
# File lib/ru_numerals.rb, line 614
def ru_fractional(n,gr_casus="и",grammar=nil, **options)
        improper=false
        options.each do |k,v|
                case k
                        when :improper then improper=v
                        else raise ArgumentError, %Q/Invalid option key #{k} value "#{v}"/, caller
                end
        end
        if n.kind_of?(Integer) then
                numer=n
                denom=1
        elsif n.kind_of?(Float) then
                m=n.to_s.match('([-+]?[0-9]+)\.([0-9]+)([eE]([-+][0-9]+))?')
                numer=(m[1] + m[2]).to_i
                denom_order=(m[2].length - (m[3].nil? ? 0 : m[4].to_i))
                while denom_order < 0
                        numer*=10
                        denom_order+=1
                end
                while numer%10 == 0 && denom_order > 0
                        numer/=10
                        denom_order-=1
                end
                denom=10**denom_order
        elsif n.kind_of?(Rational) then
                numer=n.numerator
                denom=n.denominator
        else
                raise ArgumentError, %Q/The number must be one of Rational, Float or Integer. Argument has class "#{n.class}", value "#{n}"/, caller
        end
        if denom == 1 then
                return ru_numeral(numer, gr_casus, grammar)
        end
        if (not improper) && numer.abs >= denom then
                t_str=ru_numeral((numer < 0 ? -(numer.abs/denom) : numer/denom),gr_casus,WHOLEGRAM)
                numer=numer.abs%denom
        else
                t_str=""
        end
        if not numer.zero? then
                t_str << " " if not t_str.empty?
                t_str << ru_numeral(numer,gr_casus,"ж") + " "
                if numer%10 == 1 then
                        t_str << ru_ordinal(denom,gr_casus,"ж")
                elsif       gr_casus == "и" then
                        t_str << ru_ordinal(denom,"р","ж",true)
                else
                        t_str << ru_ordinal(denom,gr_casus,"ж",true)
                end
        end
        t_str        + (grammar.nil? ? "" : (" " + ru_numeral(1,"р",grammar,-1)))
end
ru_kopecks(n,gr_casus="и",**options) click to toggle source

Преобразует число в текстовое представление денежной суммы в копейках (n*100)

@param [Integer,Float] n объект для преобразования
@param gr_casus [String] падеж числительного
@param [Hash] options опции
@option options [true,false] :spellkop (true) преобразовать в числительное число копеек, значение выводится в формате "%02d"
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_kopecks(2123.29)           #=> "двести двенадцать тысяч триста двадцать девять копеек"
   RuNumerals::ru_kopecks(3,"т",spellkop: false) #=> "300 копейками"
# File lib/ru_numerals.rb, line 695
def ru_kopecks(n,gr_casus="и",**options)
        ru_money(n,gr_casus,nil,KOPGRAM,options)
end
ru_money(n,gr_casus,rub_gram, kop_gram, **options) click to toggle source

Преобразует число в текстовое представление денежной суммы

@param [Integer,Float] n объект для преобразования
@param gr_casus [String] падеж числительного
@param rub_gram [String] грамматика "рублей", если nil или "", то выводятся только "копейки" со значением n*100
@param kop_gram [String] грамматика "копеек", если nil или "", то "копейки" не выводятся и их значение отбрасывается
@param [Hash] options опции
@option options [true,false] :spellrub (true) преобразовать в числительное число "рублей"
@option options [true,false] :spellkop (true) преобразовать в числительное число "копеек", значение выводится в формате "%02d"
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_money(123.029,"и",RuNumerals::RUBGRAM,RuNumerals::KOPGRAM)
            #=> "сто двадцать три рубля три копейки"
   RuNumerals::ru_money(123.029,"р",RuNumerals::RUBGRAM,RuNumerals::KOPGRAM, spellkop: false)
            #=> "ста двадцати трёх рублей 03 копеек"
   RuNumerals::ru_money(123.029,"т",nil,RuNumerals::KOPGRAM)
            #=> "двенадцатью тысячами тремястами тремя копейками"
# File lib/ru_numerals.rb, line 553
def ru_money(n,gr_casus,rub_gram, kop_gram, **options)
        if not (n.kind_of?(Integer) || n.kind_of?(Float)) then
                raise ArgumentError, %Q/The number must be Integer or Float. Argument has class "#{n.class}", value "#{n}"/, caller
        end
        n=n.to_f
        spellrub=true
        spellkop=true
        options.each do |k,v|
                case k
                        when :spellrub then spellrub=v
                        when :spellkop then spellkop=v
                        else raise ArgumentError, %Q/Invalid option key #{k} value "#{v}"/, caller
                end
        end
        if (rub_gram.nil? || rub_gram.empty?) && (kop_gram.nil? || kop_gram.empty? ) then
                raise ArgumentError, %Q/Both grammars are nil/, caller
        end
        if rub_gram.nil? || rub_gram.empty? then
                kops=(n*100).round
                if spellkop then
                        return ru_numeral(kops,gr_casus,kop_gram)
                else
                        return kops.to_s + " " + ru_numeral(kops,gr_casus,kop_gram,-1)
                end
        end
        rubs=n.truncate
        kops=((n*100)%100).round
        if spellrub then
                rub_s=ru_numeral(rubs,gr_casus,rub_gram)
        else
                rub_s=rubs.to_s + " " + ru_numeral(rubs,gr_casus,rub_gram,-1)
        end
        return rub_s if ( kop_gram.nil? || kop_gram.empty? )
        if spellkop then
                kop_s=ru_numeral(kops,gr_casus,kop_gram)
        else
                kop_s=("%02d" % kops.to_s) + " " + ru_numeral(kops,gr_casus,kop_gram,-1)
        end
        rub_s + " " + kop_s
end
ru_numeral(n,gr_casus = "и", grammar = "мн", minorder = 0) click to toggle source

Преобразует число в количественное числительное

@param [Integer] n число для преобразования @param gr_casus [String] падеж числительного @param grammar [String] грамматика @param minorder [Integer] минимальный порядок тысяч (см. примеры). Если минимальный порядок < 0, то собственно числительное не выводится @return [String] @raise [ArgumentError] @example

RuNumerals::ru_numeral(154,'д')                       #=> "ста пятидесяти четырём"
RuNumerals::ru_numeral(101,'','с',1)                  #=> "ноль тысяч сто одно"
RuNumerals::ru_numeral(1,'',RuNumerals::RUBGRAM,-1)   #=> "рубль"
RuNumerals::ru_numeral(2,'',RuNumerals::RUBGRAM,-1)   #=> "рубля"
# File lib/ru_numerals.rb, line 367
def ru_numeral(n,gr_casus = "и", grammar = "мн", minorder = 0)
        if not n.kind_of?(Integer) then
                raise ArgumentError, %Q/The number must be Integer. Argument has class "#{n.class}", value "#{n}"/, caller
        end
        gr_casus="и" if gr_casus.nil? || gr_casus.empty?
        minorder=minorder.to_i
        set_grammar(grammar)
        @animate=false if n > 10 and n%10 != 1
        casus=CASUS_STR.index(gr_casus.downcase)
        if not casus
                raise ArgumentError, %Q/The grammatical case must be one of "ирдвтп". Current value of argument is "#{gr_casus}"/, caller
        end
        if n < 0 then
                is_negative=true
                n=-n
        else
                is_negative=false
        end
        order=get_order(n)
        if order > ORDWORD.length then
                raise ArgumentError, %Q/Too big number #{n}. Max number supported is #{10**((ORDWORD.length+1)*3) - 1}/, caller
        end
        triad=0
        return get_tail(n%1000,casus,@animate,0) if minorder < 0
        t_str= is_negative ? "минус " : ""
        [[minorder,ORDWORD.length].min,order].max.downto(0) do |i|
                triad=(n/(10**(3*i)))%1000
                t_str << milli(triad,casus,@gender,@animate,i) + " " if triad.nonzero? || t_str.empty?
        end
        t_str << get_grammar(0,1,1) if triad.zero? && n.nonzero?
        t_str.rstrip
end
ru_ordinal(n, gr_casus = "и", grammar = "мн", plural = false) click to toggle source

Преобразует число в порядковое числительное

@param [Integer] n число для преобразования
@param gr_casus [String] падеж числительного
@param grammar [String] грамматика
@param plural [true,false] множественное число
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_ordinal(1)                 #=> "первый"
   RuNumerals::ru_ordinal(2)                 #=> "второй"           
   RuNumerals::ru_ordinal(250000000,'в','ж') #=> "двухсотпятидесятимиллионную"
   RuNumerals::ru_ordinal(5,'т','ж',true)    #=> "пятыми"
   RuNumerals::ru_ordinal(-5,'в','о')        #=> "минус пятого"
# File lib/ru_numerals.rb, line 417
def ru_ordinal(n, gr_casus = "и", grammar = "мн", plural = false)
        if not n.kind_of?(Integer) then
                raise ArgumentError, %Q/The number must be Integer. Argument has class "#{n.class}", value "#{n}"/, caller
        end
        gr_casus="и" if gr_casus.nil? || gr_casus.empty?
        set_grammar(grammar)
        casus=CASUS_STR.index(gr_casus.downcase)
        if not casus
                raise ArgumentError, %Q/The grammatical case must be one of "ирдвтп". Current value of argument is "#{gr_casus}"/, caller
        end
        if n < 0 then
                is_negative=true
                n=-n
        else
                is_negative=false
        end
        order=get_order(n)
        if order > ORDWORD.length then
                raise ArgumentError, %Q/Too big number #{n}. Max number supported is  #{10**((ORDWORD.length+1)*3) - 1}/, caller
        end
        @gender=3 if plural
        if n.zero? then
                return (ORDINALS[0] + get_ending(0,@animate, @gender, casus) + " " + get_grammar(0, plural ? 1 : 0 , casus)).rstrip
        end
        t_str = first_ordinal(n%1000,@animate,@gender,casus)
        1.upto(get_order(n)) do |i|
                triad=(n/(10**(3*i)))%1000
                if triad.nonzero? then
                        if not t_str.empty? then
                                t_str = (triad == 1 ? get_grammar(i,0,0) : milli(triad,0,0,false,i)) + " " + t_str
                        else
                                t_str = second_ordinal(triad, i, @animate, @gender, casus)
                        end
                end
        end
        (( is_negative ? "минус " : "" ) + t_str + " " + get_grammar(0, plural ? 1 : 0, casus)).rstrip
end
ru_rubles(n,gr_casus="и",**options) click to toggle source

Преобразует число в текстовое представление денежной суммы в рублях. Дробная часть отбрасываются.

@param [Integer,Float] n объект для преобразования
@param gr_casus [String] падеж числительного
@param [Hash] options опции
@option options [true,false] :spellrub (true) преобразовать в числительное число рублей
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_rubles(2123.29)           #=> "две тысячи сто двадцать три рубля"
   RuNumerals::ru_rubles(3,"т", spellrub: false) #=> "3 рублями"
# File lib/ru_numerals.rb, line 679
def ru_rubles(n,gr_casus="и",**options)
        ru_money(n,gr_casus,RUBGRAM,nil,options)
end
ru_rubleskopecks(n,gr_casus="и",**options) click to toggle source

Преобразует число в текстовое представление денежной суммы в рублях и копейках

@param [Integer,Float] n объект для преобразования
@param gr_casus [String] падеж числительного
@param [Hash] options опции
@option options [true,false] :spellrub (true) преобразовать в числительное число рублей
@option options [true,false] :spellkop (true) преобразовать в числительное число копеек, значение выводится в формате "%02d"
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_rubleskopecks(2123.29)           #=> "две тысячи сто двадцать три рубля двадцать девять копеек"
   RuNumerals::ru_rubleskopecks(3,"т",spellkop: false) #=> "тремя рублями 00 копеек"
# File lib/ru_numerals.rb, line 712
def ru_rubleskopecks(n,gr_casus="и",**options)
        ru_money(n,gr_casus,RUBGRAM,KOPGRAM,options)
end
ru_time(d, gr_casus="и", **options) click to toggle source

Преобразует объект класса Time в текстовое представление времени

@param [Time] d объект для преобразования
@param gr_casus [String] падеж числительного
@param [Hash] options опции
@option options [true,false] :spellhh (true) преобразовать в числительное часы
@option options [true,false] :spellmm (true) преобразовать в числительное минуты
@option options [true,false] :spellss (true) преобразовать в числительное секунды
@option options [true,false] :seconds (true) показывать секунды
@return [String]
@raise [ArgumentError]
@example

   RuNumerals::ru_time(Time.now)                                      
           #=> "восемнадцать часов пятьдесят две минуты двадцать секунд"
   RuNumerals::ru_time(Time.now,"д",spellhh: false , spellmm: false , spellss: false)
           #=> "18 часам 52 минутам 20 секундам"
   RuNumerals::ru_time(Time.now,'',spellhh: false , spellmm: false , noseconds: false)
           #=> "18 часов 52 минуты"
# File lib/ru_numerals.rb, line 511
def ru_time(d, gr_casus="и", **options)
        if not d.kind_of?(Time) then
                raise ArgumentError, %Q/The argument must be Time class. Argument has class "#{d.class}", value "#{d}"/, caller
        end
        spellhh=true
        spellmm=true
        spellss=true
        seconds=true
        options.each do |k,v|
                case k
                        when :spellhh then spellhh=v
                        when :spellmm then spellmm=v
                        when :spellss then spellss=v
                        when :seconds then seconds=v
                        else raise ArgumentError, %Q/Invalid option key #{k} value "#{v}"/, caller
                end
        end
        (spellhh ? ru_numeral(d.hour, gr_casus, HOURGRAM ) : (d.hour.to_s + " " + ru_numeral(d.hour, gr_casus, HOURGRAM, -1 ))) + " " + 
        (spellmm ? ru_numeral(d.min, gr_casus, MINGRAM ) : (d.min.to_s + " "+ ru_numeral(d.min, gr_casus, MINGRAM, -1 ))) + 
        (seconds ?  ( " " + (spellss ? ru_numeral(d.sec, gr_casus, SECGRAM ) : (d.sec.to_s + " " + ru_numeral(d.sec, gr_casus, SECGRAM, -1 )))) : "")
end

Private Class Methods

first_ordinal(n, animate, gender, casus ) click to toggle source
# File lib/ru_numerals.rb, line 301
def first_ordinal(n, animate, gender, casus )
        return "" if n.zero?
        t_str=""
        digit=n/100
        if digit.nonzero? then
                if (n%100).zero? then
                        if digit > 1 then
                                t_str=ONES[digit][1]
                        end
                        return t_str + "сот" + get_ending(1,animate,gender,casus)
                end
                t_str=HUNDREDS[digit][0] + " "
        end
        digit=(n%100)/10
        return t_str + TEENS[n%10] + get_ending(1,animate,gender,casus) if digit == 1
        if digit !=0 then
                if (n%10).zero? then
                        return t_str + TIES[digit] + (digit == 4 ? get_ending(0,animate,gender,casus) : get_ending(1,animate,gender,casus))
                else
                        t_str << TWENTIES[digit][0] + " "
                end
        end
        digit=n%10
        t_str + ORDINALS[digit] + get_ending(digit,animate,gender,casus)
end
get_ending(n, animate, gender, casus) click to toggle source
# File lib/ru_numerals.rb, line 287
def get_ending(n, animate, gender, casus)
        if ( animate || gender == 1 ) && casus == 3 then
                return  n == 3 ? ACCUSATIVE3[gender] : ACCUSATIVE[gender]
        end
        case n
                when 0,2,6,7,8 then
                        return ENDING02678[gender][casus]
                when 1,4,5,9 then
                        return ENDING1459[gender][casus]
                when 3
                        return ENDING3[gender][casus]
        end
end
get_grammar(order, plural, casus) click to toggle source
# File lib/ru_numerals.rb, line 176
def get_grammar(order, plural, casus)
        if order == 0 then
                @usergram[plural][casus]
        elsif order == 1  then
                ORDWORD[order] + THOU_ENDING[plural][casus]
        else
                ORDWORD[order] + MILLI_ENDING[plural][casus]
        end
end
get_order(n) click to toggle source
# File lib/ru_numerals.rb, line 186
def get_order(n)
        order=1
        order+=1 until n < 10 ** (3*order)
        order-1
end
get_tail(n, casus, animate, order) click to toggle source
# File lib/ru_numerals.rb, line 222
def get_tail(n, casus, animate, order)
        return get_grammar(order,1,1) if n.zero?
        t_n=n
        tail=get_grammar(order,1, casus == 0 || casus == 3 ? 1 : casus )
        t_n = t_n%100
        t_n = t_n%10 if t_n >= 20
        return tail if t_n == 0 || t_n >= 10
        if t_n == 1 then
                tail=get_grammar(order,0,casus)
        elsif ( t_n >=2 && t_n <=4 ) && ( casus == 0 || casus == 3 ) then
                tail = get_grammar(order, animate && casus == 3 ? 1 : 0 , 1 )
        else
                tail = get_grammar(order, 1, casus == 0 || casus == 3 ? 1 : casus)
        end
        tail
end
milli(n, casus, gender, animate, order) click to toggle source
# File lib/ru_numerals.rb, line 239
def milli(n, casus, gender, animate, order)
        t_n=n
        if order != 0 then
                t_gender=(order == 1 ? 1 : 0)
                t_animate=false
        else
                t_gender=gender
                t_animate=animate
        end
        tail=get_tail(t_n,casus,t_animate,order)
        return ONES[0][casus] + " " + tail if t_n.zero?
        t_str=""
        if t_n >= 100 then
                t_str+=HUNDREDS[t_n/100][casus]
                t_n=t_n%100
        end
        if t_n >=20 then
                t_str << " " if not t_str.empty?
                t_str << TWENTIES[t_n/10][casus]
                t_n = t_n%10
        end
        if t_n >=10 then
                t_str << " " if not t_str.empty?
                t_str << TEENS[t_n%10] + TEENCASES[casus]
                t_n = 0
        end
        return t_str + " " + tail if t_n == 0
        t_str << " " if not t_str.empty?
        if t_n == 1 then
                if t_animate && casus == 3 then
                        t_str << (t_gender == 0 ? ONES[1][1] : ONES1[t_gender][3])
                else
                        t_str << (t_gender == 0 ? ONES[1][casus] : ONES1[t_gender][casus])
                end
        elsif t_n == 2 then
                if t_animate && casus == 3 then
                        t_str << (t_gender == 0 ? ONES[2][1] : ONES2[t_gender][1])
                else
                        t_str << (t_gender == 0 ? ONES[2][casus] : ONES2[t_gender][casus])
                end
        elsif t_animate && t_n <=4 && casus == 3 then
                t_str << ONES[t_n][1]
        else
                t_str << ONES[t_n][casus]           
        end
        t_str << " " + tail
end
second_ordinal(n,order,animate, gender, casus ) click to toggle source
# File lib/ru_numerals.rb, line 327
def second_ordinal(n,order,animate, gender, casus )
        return "" if n.zero?
        t_str=""
        if n != 1 then
                digit=n/100
                if digit.nonzero? then
                        if digit == 1 
                                t_str= (n%100).zero? ? "сто" : "ста"
                        else
                                t_str= ONES[digit][1] + "сот"
                        end
                end
                digit=(n%100)/10
                if digit == 1 then
                        t_str << TEENS[n%10] + TEENCASES[1]
                else
                        t_str << TWENTIES[digit][1] if digit != 0
                        digit=n%10
                        t_str << COMPOUNDS[digit] if digit != 0
                end
        end
        t_str + ORDWORD[order] + "н" + get_ending(1,animate,gender,casus)
end
set_grammar(grammar) click to toggle source
# File lib/ru_numerals.rb, line 192
def set_grammar(grammar)
        @gender=0
        @animate=false
        @usergram = [["","","","","",""],["","","","","",""]]
        t_ar=grammar.to_s.split("|")
        return if t_ar.empty?
        t_ar[0].downcase.each_char do |c|
                case c
                        when "м" then
                                @gender=0
                        when "ж" then
                                @gender=1
                        when "с" then
                                @gender=2
                        when "н"
                                @animate=false
                        when "о"
                                @animate=true
                        else
                                raise ArgumentError, %Q/Invalid grammar specified "#{s}"/, caller
                end
        end
        0.upto(1) do |i|
                0.upto(5) do |j|
                        c_gr=t_ar[6*i + j + 1]
                        @usergram[i][j] =  c_gr ? c_gr : ""
                end
        end
end