Module:User:Anomie/deepToString

local p = {}

local function deepToString( val, indent, done )
    done = done or {}
    indent = indent or 0

    local tp = type( val )
    if tp == 'string' then
        return string.format( "%q", val )
    elseif tp == 'table' then
        if done[val] then return '{ ... }' end
        done[val] = true
        local sb = { '{\n' }
        local donekeys = {}
        for key, value in ipairs( val ) do
            donekeys[key] = true
            sb[#sb + 1] = string.rep( " ", indent + 2 )
            sb[#sb + 1] = deepToString( value, indent + 2, done )
            sb[#sb + 1] = ",\n"
        end
        local keys = {}
        for key in pairs( val ) do
            if not donekeys[key] then
                keys[#keys + 1] = key
            end
        end
        table.sort( keys )
        for i = 1, #keys do
            local key = keys[i]
            sb[#sb + 1] = string.rep( " ", indent + 2 )
            if type( key ) == 'table' then
                sb[#sb + 1] = '[{ ... }] = '
            else
                sb[#sb + 1] = '['
                sb[#sb + 1] = deepToString( key, indent + 3, done )
                sb[#sb + 1] = '] = '
            end
            sb[#sb + 1] = deepToString( val[key], indent + 2, done )
            sb[#sb + 1] = ",\n"
        end
        sb[#sb + 1] = string.rep( " ", indent )
        sb[#sb + 1] = "}"
        return table.concat( sb )
    else
        return tostring( val )
    end
end
p.deepToString = deepToString

return p