Hi Hans,

I think the verbose.spanish code you put in the latest beta broke
verbose.english: after verbose.english is defined, a second `local
verbose = { }` at the start of the spanish code accidentally
overwrites that table.

The code below works; as a bonus, it fixes the bug where 900 was
printed as 'nine hundred zero'. It can replace the entire swath of
verbose-related code, right up to the handlers. (The English part is
mostly untouched; only that bugfix, and a tweak to use the `local
words = words.english` idiom)

Known bugs:
* 100 before 'mil' should be 'cien mil'
* 100 on its own should be 'cien'
* 100 before 'millón' -- should that be 'cien millón', or 'ciento millón'?
* what are the rules for e.g. '1001' -- should that be 'mil y una'?
And should 1004 also be mil y cuatro?

Acidrums: if you put this in core-con.lua, replacing everything
between the commands.ordinal and converters.verbose function
definitions, then run context --make cont-en, does the output look
okay to you? Also: thank you for the day and month tables!
Cheers,
Sietse

-- verbose numbers

local verbose = { }

-- verbose english

local words = { }

words.english = {
        [0] = "zero",
        [1] = "one",
        [2] = "two",
        [3] = "three",
        [4] = "four",
        [5] = "five",
        [6] = "six",
        [7] = "seven",
        [8] = "eight",
        [9] = "nine",
       [10] = "ten",
       [11] = "eleven",
       [12] = "twelve",
       [13] = "thirteen",
       [14] = "fourteen",
       [15] = "fifteen",
       [16] = "sixteen",
       [17] = "seventeen",
       [18] = "eighteen",
       [19] = "nineteen",
       [20] = "twenty",
       [30] = "thirty",
       [40] = "forty",
       [50] = "fifty",
       [60] = "sixty",
       [70] = "seventy",
       [80] = "eighty",
       [90] = "ninety",
      [100] = "hundred",
     [1000] = "thousand",
   [1000^2] = "million",
   [1000^3] = "billion",
   [1000^4] = "trillion",
}

function verbose.english(n)
    local words = words.english
    local w = words[n]
    if w then
        return w
    end
    local t = { }
    local function compose_one(n)
        local w = words[n]
        if w then
            t[#t+1] = w
            return
        end
        local a, b = floor(n/100), n % 100
        if a == 10 then
            t[#t+1] = words[1]
            t[#t+1] = words[1000]
        elseif a > 0 then
            t[#t+1] = words[a]
            t[#t+1] = words[100]
            -- don't say 'nine hundred zero'
            if b == 0 then
                return
            end
        end
        if words[b] then
            t[#t+1] = words[b]
        else
            a, b = floor(b/10), n % 10
            t[#t+1] = words[a*10]
            t[#t+1] = words[b]
        end
    end
    local function compose_two(n,m)
        if n > (m-1) then
            local a, b = floor(n/m), n % m
            if a > 0 then
                compose_one(a)
            end
            t[#t+1] = words[m]
            n = b
        end
        return n
    end
    n = compose_two(n,1000^4)
    n = compose_two(n,1000^3)
    n = compose_two(n,1000^2)
    n = compose_two(n,1000^1)
    if n > 0 then
        compose_one(n)
    end
    return #t > 0 and concat(t," ") or tostring(n)
end

verbose.en = verbose.english

-- print(verbose.english(11111111))
-- print(verbose.english(2221101))
-- print(verbose.english(1111))
-- print(verbose.english(1218))
-- print(verbose.english(1234))
-- print(verbose.english(12345))
-- print(verbose.english(12345678900000))

-- verbose spanish (unchecked)

words.spanish = {
        [1] = "uno",
        [2] = "dos",
        [3] = "tres",
        [4] = "cuatro",
        [5] = "cinco",
        [6] = "seis",
        [7] = "siete",
        [8] = "ocho",
        [9] = "nueve",
       [10] = "diez",
       [11] = "once",
       [12] = "doce",
       [13] = "trece",
       [14] = "catorce",
       [15] = "quince",
       [16] = "dieciséis",
       [17] = "diecisiete",
       [18] = "dieciocho",
       [19] = "diecinueve",
       [20] = "veinte",
       [21] = "veintiuno",
       [22] = "veintidós",
       [23] = "veintitrés",
       [24] = "veinticuatro",
       [25] = "veinticinco",
       [26] = "veintiséis",
       [27] = "veintisiete",
       [28] = "veintiocho",
       [29] = "veintinueve",
       [30] = "treinta",
       [40] = "cuarenta",
       [50] = "cincuenta",
       [60] = "sesenta",
       [70] = "setenta",
       [80] = "ochenta",
       [90] = "noventa",
      [100] = "ciento",
      [200] = "doscientos",
      [300] = "trescientos",
      [400] = "cuatrocientos",
      [500] = "quinientos",
      [600] = "seiscientos",
      [700] = "setecientos",
      [800] = "ochocientos",
      [900] = "novecientos",
     [1000] = "mil",
   [1000^2] = "millón",
   [1000^3] = "mil millónes",
   [1000^4] = "billón",
}

function verbose.spanish(n)
    local words = words.spanish
    local w = words[n]
    if w then
        return w
    end
    local t = { }
    local function compose_one(n)
        local w = words[n]
        if w then
            t[#t+1] = w
            return
        end
        -- a, b = hundreds, remainder
        local a, b = floor(n/100), n % 100
        -- one thousand
        if a == 10 then
            t[#t+1] = words[1]
            t[#t+1] = words[1000]
        -- x hundred (n.b. this will not give thirteen hundred because
        -- compose_one(n) is only called after
        -- `n = compose(two(n, 1000^1))`.
        elseif a > 0 then
            t[#t+1] = words[a*100]
        end
        -- the remainder
        if words[b] then
            t[#t+1] = words[b]
        else
            -- a, b = tens, remainder
            a, b = floor(b/10), n % 10
            t[#t+1] = words[a*10]
            t[#t+1] = "y"
            t[#t+1] = words[b]
        end
    end
    -- compose_two handles x billion, ... x thousand. When 1000 or less is
    -- left, compose_one takes over.
    local function compose_two(n,m)
        if n > (m-1) then
            local a, b = floor(n/m), n % m
            if a > 0 then
                compose_one(a)
            end
            t[#t+1] = words[m]
            n = b
        end
        return n
    end
    n = compose_two(n,1000^4)
    n = compose_two(n,1000^3)
    n = compose_two(n,1000^2)
    n = compose_two(n,1000^1)
    if n > 0 then
        compose_one(n)
    end
    return #t > 0 and concat(t," ") or tostring(n)
end

verbose.es = verbose.spanish

-- print(verbose.spanish(31))
-- print(verbose.spanish(101))
-- print(verbose.spanish(199))

---- verbose handlers come next) ----
___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the 
Wiki!

maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
webpage  : http://www.pragma-ade.nl / http://tex.aanhet.net
archive  : http://foundry.supelec.fr/projects/contextrev/
wiki     : http://contextgarden.net
___________________________________________________________________________________

Reply via email to