From Wikipedia, the free encyclopedia


require('strict')

local libraryUtil = require("libraryUtil")

local checkType = libraryUtil.checkType

local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg



local defaultOptions = {

	pretty = false,

	tabs = true,

	semicolons = false,

	spaces = 4,

	sortKeys = true,

	depth = 0,

}



-- Define the reprRecursive variable here so that we can call the reprRecursive

-- function from renderSequence and renderKeyValueTable without getting

-- "Tried to read nil global reprRecursive" errors.

local reprRecursive



local luaKeywords = {

	"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,

}



--[[

-- Whether the given value is a valid Lua identifier (i.e. whether it can be

-- used as a variable name.)

--]]

local function isLuaIdentifier(str)

	return type(str) == "string"

		-- Must start with a-z, A-Z or underscore, and can only contain

		-- a-z, A-Z, 0-9 and underscore

		and str:find("^[%a_][%a%d_]*$") ~= nil

		-- Cannot be a Lua keyword

		and not luaKeywordsstr

end



--[[

-- Render a string representation.

--]]

local function renderString(s)

	return (("%q"):format(s):gsub("\\\n", "\\n"))

end



--[[

-- Render a number representation.

--]]

local function renderNumber(n)

	if n == math.huge then

		return "math.huge"

	elseif n == -math.huge then

		return "-math.huge"

	else

		return tostring(n)

	end

end



--[[

-- Whether a table has a __tostring metamethod.

--]]

local function hasTostringMetamethod(t)

	return getmetatable(t) and type(getmetatable(t).__tostring) == "function"

end



--[[

-- Pretty print a sequence of string representations.

-- This can be made to represent different constructs depending on the values

-- of prefix, suffix, and separator. The amount of whitespace is controlled by

-- the depth and indent parameters.

--]]

local function prettyPrintItemsAtDepth(items, prefix, suffix, separator, indent, depth)

	local whitespaceAtCurrentDepth = "\n" .. indent:rep(depth)

	local whitespaceAtNextDepth = whitespaceAtCurrentDepth .. indent

	local ret = {prefix, whitespaceAtNextDepth}

	local first = items1

	if first ~= nil then

		table.insert(ret, first)

	end

	for i = 2, #items do

		table.insert(ret, separator)

		table.insert(ret, whitespaceAtNextDepth)

		table.insert(ret, itemsi])

	end

	table.insert(ret, whitespaceAtCurrentDepth)

	table.insert(ret, suffix)

	return table.concat(ret)

end



--[[

-- Render a sequence of string representations.

-- This can be made to represent different constructs depending on the values of

-- prefix, suffix and separator.

--]]

local function renderItems(items, prefix, suffix, separator)

	return prefix .. table.concat(items, separator .. " ") .. suffix

end



--[[

-- Render a regular table (a non-cyclic table with no __tostring metamethod).

-- This can be a sequence table, a key-value table, or a mix of the two.

--]]

local function renderNormalTable(t, context, depth)

	local items = {}



	-- Render the items in the sequence part

	local seen = {}

	for i, value in ipairs(t) do

		table.insert(items, reprRecursive(ti], context, depth + 1))

		seeni = true

	end

	

	-- Render the items in the key-value part	

	local keyOrder = {}

	local keyValueStrings = {}

	for k, v in pairs(t) do

		if not seenk then

			local kStr = isLuaIdentifier(k) and k or ("[" .. reprRecursive(k, context, depth + 1) .. "]")

			local vStr = reprRecursive(v, context, depth + 1)

			table.insert(keyOrder, kStr)

			keyValueStringskStr = vStr

		end

	end

	if context.sortKeys then

		table.sort(keyOrder)

	end

	for _, kStr in ipairs(keyOrder) do

		table.insert(items, string.format("%s = %s", kStr, keyValueStringskStr]))

	end

	

	-- Render the table structure

	local prefix = "{"

	local suffix = "}"

	if context.pretty then

		return prettyPrintItemsAtDepth(

			items,

			prefix,

			suffix,

			context.separator,

			context.indent,

			depth

		)

	else

		return renderItems(items, prefix, suffix, context.separator)

	end

end



--[[

-- Render the given table.

-- As well as rendering regular tables, this function also renders cyclic tables

-- and tables with a __tostring metamethod.

--]]

local function renderTable(t, context, depth)

	if hasTostringMetamethod(t) then

		return tostring(t)

	elseif context.shownt then

		return "{CYCLIC}"

	end

	context.shownt = true

	local result = renderNormalTable(t, context, depth)

	context.shownt = false

	return result

end



--[[

-- Recursively render a string representation of the given value.

--]]

function reprRecursive(value, context, depth)

	if value == nil then

		return "nil"

	end

	local valueType = type(value)

	if valueType == "boolean" then

		return tostring(value)

	elseif valueType == "number" then

		return renderNumber(value)

	elseif valueType == "string" then

		return renderString(value)

	elseif valueType == "table" then

		return renderTable(value, context, depth)

	else

		return "<" .. valueType .. ">"

	end

end



--[[

-- Normalize a table of options passed by the user.

-- Any values not specified will be assigned default values.

--]]

local function normalizeOptions(options)

	options = options or {}

	local ret = {}

	for option, defaultValue in pairs(defaultOptions) do

		local value = optionsoption

		if value ~= nil then

			if type(value) == type(defaultValue) then

				retoption = value

			else

				error(

					string.format(

						'Invalid type for option "%s" (expected %s, received %s)',

						option,

						type(defaultValue),

						type(value)

					),

					3

				)

			end

		else

			retoption = defaultValue

		end

	end

	return ret

end



--[[

-- Get the indent from the options table.

--]]

local function getIndent(options)

	if options.tabs then

		return "\t"

	else

		return string.rep(" ", options.spaces)

	end

end



--[[

-- Render a string representation of the given value.

--]]

local function repr(value, options)

	checkType("repr", 2, options, "table", true)

	

	options = normalizeOptions(options)

	local context = {}



	context.pretty = options.pretty

	if context.pretty then

		context.indent = getIndent(options)

	else

		context.indent = ""

	end

	

	if options.semicolons then

		context.separator = ";"

	else

		context.separator = ","

	end

	

	context.sortKeys = options.sortKeys

	context.shown = {}

	local depth = options.depth

	

	return reprRecursive(value, context, depth)

end



--[[

-- Render a string representation of the given function invocation.

--]]

local function invocationRepr(keywordArgs)

	checkType("invocationRepr", 1, keywordArgs, "table")

	checkTypeForNamedArg("invocationRepr", "funcName", keywordArgs.funcName, "string")

	checkTypeForNamedArg("invocationRepr", "args", keywordArgs.args, "table", true)

	checkTypeForNamedArg("invocationRepr", "options", keywordArgs.options, "table", true)

	

	local options = normalizeOptions(keywordArgs.options)

	local depth = options.depth



	options.depth = depth + 1

	local items = {}

	if keywordArgs.args then

		for _, arg in ipairs(keywordArgs.args) do

			table.insert(items, repr(arg, options))

		end

	end



	local prefix = "("

	local suffix = ")"

	local separator = ","

	local renderedArgs

	if options.pretty then

		renderedArgs = prettyPrintItemsAtDepth(

			items,

			prefix,

			suffix,

			separator,

			getIndent(options),

			depth

		)

	else

		renderedArgs = renderItems(items, prefix, suffix, separator)

	end

	return keywordArgs.funcName .. renderedArgs

end



return {

	_isLuaIdentifier = isLuaIdentifier,

	repr = repr,

	invocationRepr = invocationRepr,

}
From Wikipedia, the free encyclopedia


require('strict')

local libraryUtil = require("libraryUtil")

local checkType = libraryUtil.checkType

local checkTypeForNamedArg = libraryUtil.checkTypeForNamedArg



local defaultOptions = {

	pretty = false,

	tabs = true,

	semicolons = false,

	spaces = 4,

	sortKeys = true,

	depth = 0,

}



-- Define the reprRecursive variable here so that we can call the reprRecursive

-- function from renderSequence and renderKeyValueTable without getting

-- "Tried to read nil global reprRecursive" errors.

local reprRecursive



local luaKeywords = {

	"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,

}



--[[

-- Whether the given value is a valid Lua identifier (i.e. whether it can be

-- used as a variable name.)

--]]

local function isLuaIdentifier(str)

	return type(str) == "string"

		-- Must start with a-z, A-Z or underscore, and can only contain

		-- a-z, A-Z, 0-9 and underscore

		and str:find("^[%a_][%a%d_]*$") ~= nil

		-- Cannot be a Lua keyword

		and not luaKeywordsstr

end



--[[

-- Render a string representation.

--]]

local function renderString(s)

	return (("%q"):format(s):gsub("\\\n", "\\n"))

end



--[[

-- Render a number representation.

--]]

local function renderNumber(n)

	if n == math.huge then

		return "math.huge"

	elseif n == -math.huge then

		return "-math.huge"

	else

		return tostring(n)

	end

end



--[[

-- Whether a table has a __tostring metamethod.

--]]

local function hasTostringMetamethod(t)

	return getmetatable(t) and type(getmetatable(t).__tostring) == "function"

end



--[[

-- Pretty print a sequence of string representations.

-- This can be made to represent different constructs depending on the values

-- of prefix, suffix, and separator. The amount of whitespace is controlled by

-- the depth and indent parameters.

--]]

local function prettyPrintItemsAtDepth(items, prefix, suffix, separator, indent, depth)

	local whitespaceAtCurrentDepth = "\n" .. indent:rep(depth)

	local whitespaceAtNextDepth = whitespaceAtCurrentDepth .. indent

	local ret = {prefix, whitespaceAtNextDepth}

	local first = items1

	if first ~= nil then

		table.insert(ret, first)

	end

	for i = 2, #items do

		table.insert(ret, separator)

		table.insert(ret, whitespaceAtNextDepth)

		table.insert(ret, itemsi])

	end

	table.insert(ret, whitespaceAtCurrentDepth)

	table.insert(ret, suffix)

	return table.concat(ret)

end



--[[

-- Render a sequence of string representations.

-- This can be made to represent different constructs depending on the values of

-- prefix, suffix and separator.

--]]

local function renderItems(items, prefix, suffix, separator)

	return prefix .. table.concat(items, separator .. " ") .. suffix

end



--[[

-- Render a regular table (a non-cyclic table with no __tostring metamethod).

-- This can be a sequence table, a key-value table, or a mix of the two.

--]]

local function renderNormalTable(t, context, depth)

	local items = {}



	-- Render the items in the sequence part

	local seen = {}

	for i, value in ipairs(t) do

		table.insert(items, reprRecursive(ti], context, depth + 1))

		seeni = true

	end

	

	-- Render the items in the key-value part	

	local keyOrder = {}

	local keyValueStrings = {}

	for k, v in pairs(t) do

		if not seenk then

			local kStr = isLuaIdentifier(k) and k or ("[" .. reprRecursive(k, context, depth + 1) .. "]")

			local vStr = reprRecursive(v, context, depth + 1)

			table.insert(keyOrder, kStr)

			keyValueStringskStr = vStr

		end

	end

	if context.sortKeys then

		table.sort(keyOrder)

	end

	for _, kStr in ipairs(keyOrder) do

		table.insert(items, string.format("%s = %s", kStr, keyValueStringskStr]))

	end

	

	-- Render the table structure

	local prefix = "{"

	local suffix = "}"

	if context.pretty then

		return prettyPrintItemsAtDepth(

			items,

			prefix,

			suffix,

			context.separator,

			context.indent,

			depth

		)

	else

		return renderItems(items, prefix, suffix, context.separator)

	end

end



--[[

-- Render the given table.

-- As well as rendering regular tables, this function also renders cyclic tables

-- and tables with a __tostring metamethod.

--]]

local function renderTable(t, context, depth)

	if hasTostringMetamethod(t) then

		return tostring(t)

	elseif context.shownt then

		return "{CYCLIC}"

	end

	context.shownt = true

	local result = renderNormalTable(t, context, depth)

	context.shownt = false

	return result

end



--[[

-- Recursively render a string representation of the given value.

--]]

function reprRecursive(value, context, depth)

	if value == nil then

		return "nil"

	end

	local valueType = type(value)

	if valueType == "boolean" then

		return tostring(value)

	elseif valueType == "number" then

		return renderNumber(value)

	elseif valueType == "string" then

		return renderString(value)

	elseif valueType == "table" then

		return renderTable(value, context, depth)

	else

		return "<" .. valueType .. ">"

	end

end



--[[

-- Normalize a table of options passed by the user.

-- Any values not specified will be assigned default values.

--]]

local function normalizeOptions(options)

	options = options or {}

	local ret = {}

	for option, defaultValue in pairs(defaultOptions) do

		local value = optionsoption

		if value ~= nil then

			if type(value) == type(defaultValue) then

				retoption = value

			else

				error(

					string.format(

						'Invalid type for option "%s" (expected %s, received %s)',

						option,

						type(defaultValue),

						type(value)

					),

					3

				)

			end

		else

			retoption = defaultValue

		end

	end

	return ret

end



--[[

-- Get the indent from the options table.

--]]

local function getIndent(options)

	if options.tabs then

		return "\t"

	else

		return string.rep(" ", options.spaces)

	end

end



--[[

-- Render a string representation of the given value.

--]]

local function repr(value, options)

	checkType("repr", 2, options, "table", true)

	

	options = normalizeOptions(options)

	local context = {}



	context.pretty = options.pretty

	if context.pretty then

		context.indent = getIndent(options)

	else

		context.indent = ""

	end

	

	if options.semicolons then

		context.separator = ";"

	else

		context.separator = ","

	end

	

	context.sortKeys = options.sortKeys

	context.shown = {}

	local depth = options.depth

	

	return reprRecursive(value, context, depth)

end



--[[

-- Render a string representation of the given function invocation.

--]]

local function invocationRepr(keywordArgs)

	checkType("invocationRepr", 1, keywordArgs, "table")

	checkTypeForNamedArg("invocationRepr", "funcName", keywordArgs.funcName, "string")

	checkTypeForNamedArg("invocationRepr", "args", keywordArgs.args, "table", true)

	checkTypeForNamedArg("invocationRepr", "options", keywordArgs.options, "table", true)

	

	local options = normalizeOptions(keywordArgs.options)

	local depth = options.depth



	options.depth = depth + 1

	local items = {}

	if keywordArgs.args then

		for _, arg in ipairs(keywordArgs.args) do

			table.insert(items, repr(arg, options))

		end

	end



	local prefix = "("

	local suffix = ")"

	local separator = ","

	local renderedArgs

	if options.pretty then

		renderedArgs = prettyPrintItemsAtDepth(

			items,

			prefix,

			suffix,

			separator,

			getIndent(options),

			depth

		)

	else

		renderedArgs = renderItems(items, prefix, suffix, separator)

	end

	return keywordArgs.funcName .. renderedArgs

end



return {

	_isLuaIdentifier = isLuaIdentifier,

	repr = repr,

	invocationRepr = invocationRepr,

}

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook