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