Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

table.Print - a better version of PrintTable #2033

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion garrysmod/lua/includes/extensions/table.lua
Original file line number Diff line number Diff line change
Expand Up @@ -800,4 +800,4 @@ if ( !table.move ) then
return destTbl

end
end
end
193 changes: 193 additions & 0 deletions garrysmod/lua/includes/extensions/table/print.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
local white = Color( 230, 230, 230 )
local red = Color( 212, 53, 109 )
local yellow = Color( 212, 202, 107 )
local purple = Color( 157, 110, 212 )
local cyan = Color( 102, 217, 239 )
local dark = Color( 105, 105, 105 )

local IsValidKeyName

do
local reserved = { [ "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}

function IsValidKeyName( key )
-- name cant be reserved word
if reserved[ key ] then return false end

-- it should start with letters or underscore, It should continue with alphanumerics
if ( key:match( "^[%a_][%w_]*$" ) == nil ) then return false end

return true
end
end

local MsgC = MsgC

if SERVER and system.IsLinux() then
function MsgC( ... ) -- polyfill to make MsgC works in linux srcds
for _, v in ipairs( { ... } ) do
if ( IsColor( v ) ) then
Msg( string.format( "\27[38;2;%d;%d;%dm", v.r, v.g, v.b ) )
else
Msg( v )
end
end

Msg("\27[0m")
end
end

local function Round( num )
return math.Round( num, 3 )
end

local gmodObjects = {}

function gmodObjects.Player( v )
MsgC( cyan, "Player", white, "( ", purple, v:UserID(), white, " )" )
end

function gmodObjects.Entity( v )
MsgC( cyan, "Entity", white, "( ", purple, v:EntIndex(), white, " )" )
end

local gmodAxisObjects = { Vector = true, Angle = true }

local function MsgValue( v )
if isstring( v ) then
if v:find( "\n", 1, true ) then
MsgC( yellow, "[[", v, "]]" )
else
MsgC( yellow, "\"", v, "\"" )
end
elseif IsColor( v ) then
MsgC(
cyan, "Color", white, "( ",
purple, v.r, red, ", ",
purple, v.g, red, ", ",
purple, v.b
)

if v.a ~= 255 then
MsgC(
red, ", ",
purple, v.a
)
end

MsgC( white, " )" )
elseif gmodObjects[ type( v ) ] then
gmodObjects[ type( v ) ]( v )
elseif gmodAxisObjects[ type( v ) ] then
MsgC(
cyan, type( v ), white, "( ",
purple, Round( v[ 1 ] )
)

if v[ 2 ] ~= 0 then
MsgC( red, ", ", purple, Round( v[ 2 ] ) )
end

if v[ 3 ] ~= 0 then
MsgC( red, ", ", purple, Round( v[ 3 ] ) )
end

MsgC( white, " )" )
elseif isfunction( v ) then
local info = debug.getinfo( v )
local defined = info.linedefined == info.lastlinedefined and info.linedefined or info.linedefined .. "-" .. info.lastlinedefined

MsgC( purple, v, dark, " --[[ ", info.short_src, ":", defined, " ]]" )
else
MsgC( purple, v )
end
end

local function MsgKey( indent, k )
if ( isstring( k ) == false ) then
MsgC( indent, red, "[ " )
MsgValue( k )
MsgC( red, " ] = " )
elseif ( IsValidKeyName( k ) ) then
MsgC( indent, white, k, red, " = " )
else
MsgC( indent, red, "[ ", yellow, "\"", k, yellow, "\"", red, " ] = " )
end
end

local function tablePrint( tbl, _lvl, _done )
local len = 0
for _ in pairs( tbl ) do
len = len + 1
end

if ( len == 0 ) then
return MsgC( red, "{}\n" )
end

local isSeq = len == #tbl
local not_isSeq = not isSeq

if ( not_isSeq ) then
local new = {}
local index = 0

for k, v in pairs( tbl ) do
index = index + 1
new[ index ] = { k = k, v = v }
end

table.sort( new, function( a, b )
if ( isnumber( a.k ) and isnumber( b.k ) ) then
return a.k < b.k
end

return tostring( a.k ) < tostring( b.k )
end )

tbl = new
end

local iter = isSeq and ipairs or pairs
local indent = string.rep( "\t", _lvl )
local table_indent = string.rep( "\t", _lvl - 1 )
local i = 1

MsgC( red, "{\n" )

for k, v in iter( tbl ) do
if ( isSeq ) then
Msg( indent )
else
k, v = v.k, v.v
MsgKey( indent, k )
end

if ( istable( v ) and IsColor( v ) == false ) then
if _done[ v ] then
MsgC( purple, tostring( v ) )
else
_done[ v ] = true
tablePrint( v, _lvl + 1, _done )
end
else
MsgValue( v )
end

if i == len then
Msg( "\n" )
else
MsgC( red, ",\n" )
end

i = i + 1
end

MsgC( table_indent, red, "}" )

if ( _lvl == 1 ) then Msg( "\n" ) end
end

function table.Print( tbl )
tablePrint( tbl, 1, { [ tbl ] = true } )
end
1 change: 1 addition & 0 deletions garrysmod/lua/send.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ lua\includes\extensions\client\panel\animation.lua
lua\includes\extensions\client\panel\dragdrop.lua
lua\includes\extensions\client\panel\scriptedpanels.lua
lua\includes\extensions\client\panel\selections.lua
lua\includes\extensions\table\print.lua
lua\derma\init.lua
lua\derma\derma.lua
lua\derma\derma_example.lua
Expand Down