Code: Select all
-- from https://github.com/stevedonovan/Microlight/blob/master/ml.lua
-- http://stevedonovan.github.io/microlight/#tstring
local ml = {}
---------------------------------------------------
-- Extended table functions.
-- 'array' here is shorthand for 'array-like table'; these functions
-- only operate over the numeric `1..#t` range of a table and are
-- particularly efficient for this purpose.
-- @section table
---------------------------------------------------
local tostring = tostring -- so we can globally override tostring!
local function quote (v)
if type(v) == 'string' then
return ('%q'):format(v)
else
return tostring(v)
end
end
local lua_keyword = {
["and"] = true, ["break"] = true, ["do"] = true,
["else"] = true, ["elseif"] = true, ["end"] = true,
["false"] = true, ["for"] = true, ["function"] = true,
["if"] = true, ["in"] = true, ["local"] = true, ["nil"] = true,
["not"] = true, ["or"] = true, ["repeat"] = true,
["return"] = true, ["then"] = true, ["true"] = true,
["until"] = true, ["while"] = true, ["goto"] = true,
}
local function is_iden (key)
return key:match '^[%a_][%w_]*$' and not lua_keyword[key]
end
local tbuff
function tbuff (t,buff,k,start_indent,indent)
local start_indent2, indent2
if start_indent then
start_indent2 = indent
indent2 = indent .. indent
end
local function append (v)
if not v then return end
buff[k] = v
k = k + 1
end
local function put_item(value)
if type(value) == 'table' then
if not buff.tables[value] then
buff.tables[value] = true
k = tbuff(value,buff,k,start_indent2,indent2)
else
append("<cycle>")
end
else
value = quote(value)
append(value)
end
append ","
if start_indent then append '\n' end
end
append "{"
if start_indent then append '\n' end
-- array part -------
local array = {}
for i,value in ipairs(t) do
append(indent)
put_item(value)
array[i] = true
end
-- 'map' part ------
for key,value in pairs(t) do if not array[key] then
append(indent)
-- non-identifiers need ["key"]
if type(key)~='string' or not is_iden(key) then
if type(key)=='table' then
key = ml.tstring(key)
else
key = quote(key)
end
key = "["..key.."]"
end
append(key..'=')
put_item(value)
end end
-- removing trailing comma is done for prettiness, but this implementation
-- is not pretty at all!
local last = start_indent and buff[k-2] or buff[k-1]
if start_indent then
if last == '{' then -- empty table
k = k - 1
else
if last == ',' then -- get rid of trailing comma
k = k - 2
append '\n'
end
append(start_indent)
end
elseif last == "," then -- get rid of trailing comma
k = k - 1
end
append "}"
return k
end
--- return a string representation of a Lua value.
-- Cycles are detected, and the result can be optionally indented nicely.
-- @param t the table
-- @param how (optional) a table with fields `spacing' and 'indent', or a string corresponding
-- to `indent`.
-- @return a string
function ml.tstring (t,how)
if type(t) == 'table' and not (getmetatable(t) and getmetatable(t).__tostring) then
local buff = {tables={[t]=true}}
how = how or {}
if type(how) == 'string' then how = {indent = how} end
pcall(tbuff,t,buff,1,how.spacing or how.indent,how.indent)
return table.concat(buff)
else
return quote(t)
end
end
return ml.tstring
Code: Select all
local tstring = require"ml_tstring"
far.Show(tstring(_G," "))