Module:BaseConvert/sandbox

local p = {}

local digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'

local function normalizeFullWidthChars(s)

return mw.ustring.gsub(s, '[!-~]', function(s)

return mw.ustring.char(mw.ustring.codepoint(s, 1) - 0xFEE0)

end)

end

local function _convert(n, base, from, precision, width, default, prefix, suffix)

n = tostring(n)

-- strip off any leading '0x' (unless x is a valid digit in the input base)

from = tonumber(from)

if not from or from < 34 then

local c

n, c = n:gsub('^(-?)0[Xx]', '%1')

if c > 0 and not from then from = 16 end

end

-- check for a negative sign. Do this while the input is still in string form,

-- because tonumber doesn't support negative numbers in non-10 bases.

local sign = ''

local c

n, c = n:gsub('^-', '')

if c > 0 then sign = '-' end

-- replace any full-width Unicode characters in the string with their ASCII equivalents

n = normalizeFullWidthChars(n)

-- handle scientific notation with whitespace around the 'e' e.g. '5 e7'

n = n:gsub('%s*[eE]%s*', 'e')

from = from or 10

local num = tonumber(n, from)

base = tonumber(base)

precision = tonumber(precision)

width = tonumber(width)

if not num or not base then return default or n end

local i, f = math.modf(num)

local t = {}

repeat

local d = (i % base) + 1

i = math.floor(i / base)

table.insert(t, 1, digits:sub(d, d))

until i == 0

while #t < (width or 0) do

table.insert(t, 1, '0')

end

local intPart = table.concat(t, '')

-- compute the fractional part

local tf = {}

while f > 0 and #tf < (precision or 10) do

f = f * base

i, f = math.modf(f)

table.insert(tf, digits:sub(i + 1, i + 1))

end

-- add trailing zeros if needed

if precision and #tf < precision then

for i = 1, precision - #tf do

table.insert(tf, '0')

end

end

local fracPart = table.concat(tf, '')

-- remove trailing zeros if not needed

if not precision then

fracPart = fracPart:gsub('0*$', '')

end

-- add the radix point if needed

if #fracPart > 0 then

fracPart = '.' .. fracPart

end

return (prefix or ) .. sign .. intPart .. fracPart .. (suffix or )

end

function p.convert(frame)

-- Allow for invocation via #invoke or directly from another module

local args

if frame == mw.getCurrentFrame() then

args = frame.args

else

args = frame

end

local n = args.n

local base = args.base

local from = args.from

local precision = args.precision

local width = args.width

local default = args.default

local prefix = args.prefix

local suffix = args.suffix

return _convert(n, base, from, precision, width, default, prefix, suffix)

end

setmetatable(p, {

__index = function(t, k)

local from, base = k:match('^([0-9]+)to([0-9]+)$')

if not from then return nil end

return function(frame)

local args = frame.args

return _convert(mw.text.trim(args[1]), base, from, args.precision, args.width,

args.default, args.prefix, args.suffix)

end

end

})

return p