diff options
Diffstat (limited to 'script/json-beautify.lua')
-rw-r--r-- | script/json-beautify.lua | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/script/json-beautify.lua b/script/json-beautify.lua new file mode 100644 index 00000000..1d2a6cc0 --- /dev/null +++ b/script/json-beautify.lua @@ -0,0 +1,120 @@ +local json = require "json" +local type = type +local next = next +local error = error +local table_concat = table.concat +local table_sort = table.sort +local string_rep = string.rep +local math_type = math.type +local setmetatable = setmetatable +local getmetatable = getmetatable + +local statusMark +local statusQue +local statusDep +local statusOpt + +local defaultOpt = { + newline = "\n", + indent = " ", +} +defaultOpt.__index = defaultOpt + +local function encode_newline() + statusQue[#statusQue+1] = statusOpt.newline..string_rep(statusOpt.indent, statusDep) +end + +local encode_map = {} +for k ,v in next, json.encode_map do + encode_map[k] = v +end + +local encode_string = json.encode_map.string + +local function encode(v) + local res = encode_map[type(v)](v) + statusQue[#statusQue+1] = res +end + +function encode_map.table(t) + local first_val = next(t) + if first_val == nil then + if getmetatable(t) == json.object then + return "{}" + else + return "[]" + end + end + if statusMark[t] then + error("circular reference") + end + statusMark[t] = true + if type(first_val) == 'string' then + local key = {} + for k in next, t do + if type(k) ~= "string" then + error("invalid table: mixed or invalid key types") + end + key[#key+1] = k + end + table_sort(key) + statusQue[#statusQue+1] = "{" + statusDep = statusDep + 1 + encode_newline() + local k = key[1] + statusQue[#statusQue+1] = encode_string(k) + statusQue[#statusQue+1] = ": " + encode(t[k]) + for i = 2, #key do + local k = key[i] + statusQue[#statusQue+1] = "," + encode_newline() + statusQue[#statusQue+1] = encode_string(k) + statusQue[#statusQue+1] = ": " + encode(t[k]) + end + statusDep = statusDep - 1 + encode_newline() + statusMark[t] = nil + return "}" + else + local max = 0 + for k in next, t do + if math_type(k) ~= "integer" or k <= 0 then + error("invalid table: mixed or invalid key types") + end + if max < k then + max = k + end + end + statusQue[#statusQue+1] = "[" + statusDep = statusDep + 1 + encode_newline() + encode(t[1]) + for i = 2, max do + statusQue[#statusQue+1] = "," + encode_newline() + encode(t[i]) + end + statusDep = statusDep - 1 + encode_newline() + statusMark[t] = nil + return "]" + end +end + +local function beautify(v, option) + if type(v) == "string" then + v = json.decode(v) + end + statusMark = {} + statusQue = {} + statusDep = 0 + statusOpt = option and setmetatable(option, defaultOpt) or defaultOpt + encode(v) + return table_concat(statusQue) +end + +json.beautify = beautify + +return json |