Express numbers as string numerals.
Strings::Numeral provides conversions of numbers to numerals component for Strings.
- No monkey-patching String class
- Functional API that can be easily wrapped by other objects
- Instance based configuration
- Highly performant
Add this line to your application's Gemfile:
gem 'strings-numeral'
And then execute:
$ bundle
Or install it yourself as:
$ gem install strings-numeral
Strings::Numeral helps to express any number as a numeral in words. It exposes few methods to achieve this. For example, you can express a number as a cardinal numeral using cardinalize
:
Strings::Numeral.cardinalize(1234)
# => "one thousand, two hundred thirty four"
But you're not limited to converting integers only. It can handle decimals as well:
Strings::Numeral.cardinalize(1234.567)
# => "one thousand, two hundred thirty four and five hundred sixty seven thousandths"
For more options on how to customize formatting see configuration section.
Similarly, you can convert a number to a ordinal numeral with ordinalize
:
Strings::Numeral.ordinalize(1234)
# => "one thousand, two hundred thirty fourth"
You can also convert a number to a short ordinal:
Strings::Numeral.ordinalize(1234, short: true)
# => "1234th"
Using monetize
you can convert any number into a monetary numeral:
Strings::Numeral.monetize(1234.567)
# => "one thousand, two hundred thirty four dollars and fifty seven cents",
To turn a number into a roman numeral use romanize
:
Strings::Numeral.romanize(2020)
# => "MMXX"
The normalize
is a wrapping method for the cardinalize and ordinalize methods. By default it converts a number to cardinal numeral:
Strings::Numeral.numeralize(1234.567)
# => "one thousand, two hundred thirty four and five hundred sixty seven thousandths"
You can also make it convert to ordinal numerals using :term
option:
Strings::Numeral.numeralize(1234.567, term: :ord)
# => "one thousand, two hundred thirty fourth and five hundred sixty seven thousandths"
To express a number as a cardinal numeral use cardinalize
or cardinalise
.
Strings::Numeral.cardinalize(1234)
# => "one thousand, two hundred thirty four"
You're not limited to integers only. You can also express decimal numbers as well:
Strings::Numeral.cardinalize(123.456)
# => "one hundred twenty three and four hundred fifty six thousandths"
By default the fractional part of a decimal number is expressed as a fraction. If you wish to spell out fractional part digit by digit use :decimal
option with :digit
value:
Strings::Numeral.cardinalize(123.456, decimal: :digit)
# => "one hundred twenty three point four five six"
You may prefer to use a different delimiter for thousand's. You can do use by passing the :delimiter
option:
Strings::Numeral.cardinalize(1_234_567, delimiter: " and ")
# => "one million and two hundred thirty four thousand and five hundred sixty seven"
To change word that splits integer from factional part use :separator
option:
Strings::Numeral.cardinalize(1_234.567, separator: "dot")
# => "one thousand, two hundred thirty four dot five hundred sixty seven thousandths"
To express a number as a cardinal numeral use ordinalize
or ordinalise
.
Strings::Numeral.ordinalize(1234)
# => "one thousand, two hundred thirty fourth"
You're not limited to integers only. You can also express decimal numbers as well:
Strings::Numeral.ordinalize(123.456)
# => "one hundred twenty third and four hundred fifty six thousandths"
By default the fractional part of a decimal number is expressed as a fraction. If you wish to spell out fractional part digit by digit use :decimal
option with :digit
value:
Strings::Numeral.ordinalize(123.456, decimal: :digit)
# => "one hundred twenty third point four five six"
You may prefer to use a different delimiter for thousand's. You can do use by passing the :delimiter
option:
Strings::Numeral.ordinalize(1_234_567, delimiter: " and ")
# => "one million and two hundred thirty four thousand and five hundred sixty seventh"
To change word that splits integer from factional part use :separator
option:
Strings::Numeral.ordinalize(1_234.567, separator: "dot")
# => "one thousand, two hundred thirty fourth dot five hundred sixty seven thousandths"
To express a number as a monetary numeral use monetize
or monetise
.
Strings::Numeral.monetize(123.456)
# => "one hundred twenty three dollars and forty six cents",
By default monetize
displays money using USD
currency. You can change this with the :currency
option that as value accepts internationally recognised symbols. Currently support currencies are: EUR
, GBP
, JPY
, PLN
and USD
.
Strings::Numeral.monetize(123.456, currency: :jpy)
# => "one hundred twenty three yen and forty six sen"
To convert a number into a Roman numeral use romanize
:
Strings::Numeral.romanize(2020)
# => "MMXX"
All available configuration settings are:
currency
- Adds currency words for integer and fractional parts. SupportsEUR
,GBP
,JPY
,PLN
andUSD
. Defaults toUSD
.decimal
- Formats fractional part of a number. The:digit
value spells out every digit and the:fraction
appends divider word. Defaults to:fraction
.delimiter
- Sets the thousands delimiter. Defaults to", "
.separator
- Sets the separator between the fractional and integer parts. Defaults to"and"
for:fraction
and"point"
for:digit
option.strict
- Enables number validation for the input parameter. Defaults tofalse
.trailing_zeros
- Iftrue
keeps trailing zeros at the end of the fractional part. Defaults tofalse
.
The above settings can be passed as keyword arguments:
Strings::Numeral.cardinalize("12.100", trailing_zeros: true, decimal: :digit)
# => "twelve point one zero zero"
Or you can configure the settings for an instance during initialisation:
numeral = Strings::Numeral.new(delimiter: "; ", separator: "dot")
After initialisation, you can use configure
to change settings inside a block:
numeral.configure do |config|
config.delimiter "; "
config.separator "dot"
config.decimal :digit
config.trailing_zeros true
end
Once configured, you can use the instance like so:
numeral.cardinalize("1234.56700")
# => "one thousand; two hundred thirty four dot five six seven zero zero"
Though it is highly discouraged to pollute core Ruby classes, you can add the required methods to String
, Float
and Integer
classes using refinements.
For example, if you wish to only extend Float
class with cardinalize
method do:
module MyFloatExt
refine Float do
def cardinalize(**options)
Strings::Numeral.cardinalize(self, **options)
end
end
end
Then cardinalize
method will be available for any float number where refinement is applied:
using MyFloatExt
12.34.cardinalize
# => "twelve and thirty four"
However, if you want to include all the Strings::Numeral methods in Float
, Integer
and String
classes, you can use provided extensions file:
require "strings/numeral/extensions"
using Strings::Numeral::Extensions
Alternatively, you can choose what class you wish to refine with all the methods:
require "bigdecimal"
require "strings/numeral/extensions"
module MyBigDecimalExt
refine BigDecimal do
include Strings::Numeral::Extensions::Methods
end
end
using MyBigDecimalExt
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/strings-numeral. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
The gem is available as open source under the terms of the MIT License.
Everyone interacting in the Strings::Numeral project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
Copyright (c) 2019 Piotr Murach. See LICENSE for further details.