Quantcast
local function mixedSort(e1, e2)
	if type(e1) == type(e2) then
		return e1 < e2
	end
	return type(e1) < type(e2)
end

local function output(str)
	if str then
		io.write(str)
	end
	io.write("\n")
end

local function quotedString(str)
	return string.gsub(string.format("%q", str), "\n", "n")
end

local function varName(name)
	if type(name) == "number" then
		return string.format("[%d]", name)
	elseif type(name) == "string" then
		if name:find("^%a[%w_]+$") then
			return name
		else
			return string.format("[%s]", quotedString(name))
		end
	else
		return string.format("Unhandled name type: %q", type(name))
	end
end

function sort(tbl, name, indent)
	local indentStr
	if indent then
		indentStr = string.rep("\t", indent)
	else
		indent = 0
		indentStr = ""
	end

	output(string.format("%s%s = {", indentStr, varName(name)))

	local indexTable = {}
	for index, value in pairs(tbl) do
		table.insert(indexTable, index)
	end
	table.sort(indexTable, mixedSort)

	for _, index in ipairs(indexTable) do
		local value = tbl[index]
		if type(value) == "string" then
			output(string.format("%s\t%s = %s,", indentStr, varName(index), quotedString(value)))
		elseif type(value) == "number" then
			value = string.gsub(string.format("%f", value), "%.?0+$", "")
			output(string.format("%s\t%s = %s,", indentStr, varName(index), value))
		elseif type(value) == "table" then
			sort(value, index, indent + 1)
		elseif type(value) == "boolean" then
			output(string.format("%s\t%s = %s,", indentStr, varName(index), value and "true" or "false"))
		else
			output(string.format("%s\tUnhandled value type: %q", indentStr, type(value)))
		end
	end
	if indent > 0 then
		output(string.format("%s},", indentStr))
	else
		output("}")
	end
end