num2words-moonbit

    Convert numbers into words in pure MoonBit (EN/FR/ES/DE/IT/PT/PT_PT/RU): cardinal, ordinal, ordinal_num, year, and currency.

    num2words
    i18n
    numbers
    moonbit
    hackathon
    Download zip
    Author
    Version
    0.1.0
    License
    LGPL-2.1
    Last updated
    4 hours ago
    Downloads
    2

    No dependencies

    #668xin/num2words-moonbit

    Convert numbers into words in pure MoonBit — a port of the Python num2words library. Supports English, French, Spanish, German, Italian, Portuguese (Brazilian pt and European pt_PT) and Russian across cardinal, ordinal, ordinal_num, year and currency modes, with BigInt for large integers. Currency is native for all eight language codes with each language's upstream ISO code set (EUR by default, BRL for pt).

    #Quick start

    import "668xin/num2words-moonbit" @n2w

    @n2w.num2words_int(1234, "en", "cardinal") // "one thousand, two hundred and thirty-four"
    @n2w.num2words_int(2024, "en", "year") // "twenty twenty-four"
    @n2w.num2words_str("1234.56", "en", "cardinal") // "one thousand, two hundred and thirty-four point five six"
    @n2w.num2words_int(1000, "ru", "cardinal") // "одна тысяча"
    @n2w.num2words_currency("1234.56", "en", "EUR")
    // Ok("one thousand, two hundred and thirty-four euro, fifty-six cents")

    #API

    • num2words(value : BigInt, lang : String, to : String) -> String
    • num2words_int(value : Int, lang : String, to : String) -> String
    • num2words_float(value : Double, lang : String, to : String) -> String
    • num2words_str(value : String, lang : String, to : String) -> String
    • num2words_currency(amount : String, lang : String, code : String) -> Result[String, String]

    lang ∈ {"en","fr","es","de","it","pt","pt_PT","ru"} (default en); to ∈ {"cardinal","ordinal","ordinal_num","year","currency"} (default cardinal). Currency codes are language-dependent: en has 11 (EUR/USD/GBP/RUB/CAD/AUD/ INR/SEK/NOK/PLN/MXN), fr/de/it have 4 (EUR/USD/GBP/CNY), es 20, ru 6, pt only BRL, and pt_PT 5 (EUR/USD/GBP/CAD/AUD). The empty code "" selects the language default (EUR, or BRL for pt).

    #License

    LGPL-2.1. Derived from Python num2words (Savoirfairelinux, LGPL-2.1).

    Lang

    pub struct Lang {
    variant : Variant
    zero : String
    ones : Array[String]
    teens : Array[String]
    tens : Array[String]
    hundred : String
    thousands : Array[String]
    negative : String
    decimal : String
    comma_sep : Bool
    }

    Word tables + behaviour flags for one language.

    Lang::cardinal

    fn Lang::cardinal(self : Lang, n :
    BigInt
    ) -> String

    Lang::max_power

    fn Lang::max_power(self : Lang) -> Int

    Highest power of 1000 the language can spell (e.g. English: 11 -> 10^33).

    Lang::supports

    fn Lang::supports(self : Lang, n :
    BigInt
    ) -> Bool

    True when the magnitude of n fits inside the language's scale-word table. Scale tables are finite, so every language has a maximum supported power; values beyond it are reported as unsupported instead of indexing past the table (which would abort).

    Variant

    pub enum Variant {
    En
    Fr
    Es
    De
    It
    Pt
    PtPt
    Ru
    }

    get_lang

    fn get_lang(code : String) -> Lang

    Resolve a language code to its Lang descriptor.

    group3

    Split n (>0) into 3-digit groups from low to high, return high-to-low.

    is_valid_number

    fn is_valid_number(s : String) -> Bool

    Validate a decimal/integer string before it reaches BigInt.

    Accepted: 1234, -42, 007, 1234.56 Rejected: "", "-", "5.", ".5", "1.2.3", "12a", "abc", "--5"

    lang_de

    fn lang_de() -> Lang

    lang_en

    fn lang_en() -> Lang

    lang_es

    fn lang_es() -> Lang

    lang_fr

    fn lang_fr() -> Lang

    lang_it

    fn lang_it() -> Lang

    lang_pt

    fn lang_pt() -> Lang

    lang_pt_pt

    fn lang_pt_pt() -> Lang

    lang_ru

    fn lang_ru() -> Lang

    num2words

    fn num2words(value :
    BigInt
    , lang : String, to : String) -> String

    Spell a big integer.

    num2words_currency

    fn num2words_currency(amount : String, lang : String, code : String) -> Result[String, String]

    Spell a currency amount. code is an ISO-4217 code (case-insensitive) or "" for the language default (EUR, or BRL for pt).

    Supported code sets match upstream for every language (see COMPAT.md §4).

    Returns Err for malformed amounts, unsupported languages or codes, and amounts past the language's scale table.

    num2words_float

    fn num2words_float(value : Double, lang : String, to : String) -> String

    Spell a decimal number: integer part in words, fractional digits spelled out one by one after the decimal word (e.g. 1234.56 -> "... point five six").

    Scientific-notation values (very large or very small doubles) are expanded to a plain decimal first. Values too large for the language's scale table, and non-finite values (NaN / infinity), return "" instead of aborting. With to = "currency" the amount is rendered with the default code (EUR).

    num2words_int

    fn num2words_int(value : Int, lang : String, to : String) -> String

    Convenience wrapper for Int values.

    num2words_str

    fn num2words_str(value : String, lang : String, to : String) -> String

    Spell a number given directly as a decimal/integer string, e.g. num2words_str("1234.56", "en", "cardinal") -> "one thousand, two hundred and thirty-four point five six". Integer and arbitrarily large values are supported via BigInt.

    Malformed input returns "" instead of aborting; use num2words_str_checked when the caller needs to tell the two apart.

    num2words_str_checked

    fn num2words_str_checked(value : String, lang : String, to : String) -> Result[String, String]

    Same as num2words_str, but rejects bad input explicitly: Ok(words) on success, Err(message) when value is either malformed (Err("invalid number: ...")) or larger than the language's scale-word table (Err("magnitude out of supported range: ...")). Currency mode also reports unsupported languages through Err.

    ordinal_de

    fn ordinal_de(n :
    BigInt
    ) -> String

    ordinal_en

    fn ordinal_en(n :
    BigInt
    ) -> String

    ordinal_es

    fn ordinal_es(n :
    BigInt
    ) -> String

    ordinal_fr

    fn ordinal_fr(n :
    BigInt
    ) -> String

    ordinal_it

    fn ordinal_it(n :
    BigInt
    ) -> String

    ordinal_num_de

    fn ordinal_num_de(n :
    BigInt
    ) -> String

    ordinal_num_en

    fn ordinal_num_en(n :
    BigInt
    ) -> String

    Ordinal number with numeric suffix: 1 -> "1st", 2 -> "2nd", 12 -> "12th".

    ordinal_num_es

    fn ordinal_num_es(n :
    BigInt
    ) -> String

    ordinal_num_fr

    fn ordinal_num_fr(n :
    BigInt
    ) -> String

    ordinal_num_it

    fn ordinal_num_it(n :
    BigInt
    ) -> String

    ordinal_num_pt

    fn ordinal_num_pt(n :
    BigInt
    ) -> String

    ordinal_num_ru

    fn ordinal_num_ru(n :
    BigInt
    ) -> String

    ordinal_pt

    fn ordinal_pt(n :
    BigInt
    ) -> String

    ordinal_pt_pt

    fn ordinal_pt_pt(n :
    BigInt
    ) -> String

    ordinal_ru

    fn ordinal_ru(n :
    BigInt
    ) -> String

    year_de

    fn year_de(n :
    BigInt
    ) -> String

    German year reading (e.g. 2024 -> "zwanzig vierundzwanzig").

    year_en

    fn year_en(n :
    BigInt
    ) -> String

    year_es

    fn year_es(n :
    BigInt
    ) -> String

    Spanish year reading (e.g. 2024 -> "veinte veinticuatro").

    year_fr

    fn year_fr(n :
    BigInt
    ) -> String

    French year reading (e.g. 2024 -> "vingt vingt-quatre").

    year_it

    fn year_it(n :
    BigInt
    ) -> String

    Italian years are read as a plain cardinal ("2024" -> "duemilaventiquattro"), so this simply delegates to cardinal_it.

    year_pt

    fn year_pt(n :
    BigInt
    ) -> String

    Portuguese years are read as a plain cardinal ("2024" -> "dois mil e vinte e quatro"), so this delegates to cardinal_pt.

    year_pt_pt

    fn year_pt_pt(n :
    BigInt
    ) -> String

    European Portuguese years are read as a plain cardinal, like the Brazilian variant ("2024" -> "dois mil e vinte e quatro").

    year_ru

    fn year_ru(n :
    BigInt
    ) -> String

    Russian years are read as a plain cardinal ("2024" -> "две тысячи двадцать четыре"), so this delegates to cardinal_ru.