136 lines
3.2 KiB
Lua
136 lines
3.2 KiB
Lua
--[[ Exports a table containing one function: TabbedFile. It wraps a regular Lua file-handle, providing extra functions. Tabs can either be a number of spaces or one tab. It provides the following functions, in addition to (or replacing) the Lua standard ones:
|
|
|
|
- inc: Increments the tab count by the number given, or by 1 if nothing is given.
|
|
- dec: Decrements the tab count by the number given, or by 1 if nothing is given.
|
|
- push: Preserves the current tab count.
|
|
- pop: Restores the previously preserved tab count.
|
|
- write: An indented write; everything is written after the indent.
|
|
- writeblock: Takes a single string, breaks it down into multiple lines, and writes each line indented.
|
|
- fmt: As string.format followed by an indented write
|
|
- fmtblock: As string.format, followed by calling `writeblock`.
|
|
- rawfmt: As string.format followed by a NON-indented write.
|
|
- rawwrite: hFile:write.
|
|
|
|
|
|
Each call to one of the non-raw writing functions will indent the text.
|
|
]]
|
|
|
|
local members = {}
|
|
|
|
function members:inc(count)
|
|
count = count or 1
|
|
rawset(self, "_indent", self._indent + count)
|
|
end
|
|
|
|
function members:dec(count)
|
|
count = count or 1
|
|
rawset(self, "_indent", self._indent - count)
|
|
end
|
|
|
|
function members:push()
|
|
local stack = rawget(self, "_indentStack")
|
|
stack[#stack + 1] = rawget(self, "_indent")
|
|
end
|
|
|
|
function members:pop()
|
|
local stack = rawget(self, "_indentStack")
|
|
assert(#stack > 0, "Tab stack underflow.")
|
|
rawset(self, "_indent", stack[#stack])
|
|
stack[#stack] = nil
|
|
end
|
|
|
|
function members:fmt(fmt, ...)
|
|
self:_Indent()
|
|
local str = fmt:format(...)
|
|
rawget(self, "_hFile"):write(str)
|
|
end
|
|
|
|
function members:rawfmt(fmt, ...)
|
|
local str = fmt:format(...)
|
|
rawget(self, "_hFile"):write(str)
|
|
end
|
|
|
|
function members:write(...)
|
|
self:_Indent()
|
|
rawget(self, "_hFile"):write(...)
|
|
end
|
|
|
|
function members:writeblock(block, ...)
|
|
assert(#{...} == 0, "writeblock takes one argument")
|
|
for line in block:gmatch("([^\n]*)\n") do
|
|
self:write(line, "\n")
|
|
end
|
|
|
|
local last = block:match("\n([^\n]*)$")
|
|
if(last and #last ~= 0) then
|
|
self:write(last)
|
|
end
|
|
end
|
|
|
|
function members:fmtblock(block, ...)
|
|
self:writeblock(block:format(...))
|
|
end
|
|
|
|
function members:rawwrite(...)
|
|
rawget(self, "_hFile"):write(...)
|
|
end
|
|
|
|
-----------------------------------------------------
|
|
-- Standard members
|
|
local fileMembers =
|
|
{
|
|
"close",
|
|
"flush",
|
|
"lines",
|
|
"read",
|
|
"seek",
|
|
"setvbuf",
|
|
"write",
|
|
}
|
|
|
|
for _, fileMem in ipairs(fileMembers) do
|
|
if(not members[fileMem]) then
|
|
members[fileMem] = function(self, ...)
|
|
local hFile = rawget(self, "_hFile")
|
|
return hFile[fileMem](hFile, ...)
|
|
end
|
|
end
|
|
end
|
|
|
|
local metatable = {}
|
|
|
|
function metatable.__index(self, key)
|
|
return members[key]
|
|
end
|
|
|
|
metatable.__newindex = {}
|
|
|
|
local function IndentFunc(self)
|
|
self._hFile:write(string.rep(self._indentStr, self._indent))
|
|
end
|
|
|
|
local function TabbedFile(hFile, style, numSpaces)
|
|
numSpaces = numSpaces or 2
|
|
|
|
local proxy =
|
|
{
|
|
_hFile = hFile,
|
|
_indent = 0,
|
|
_Indent = IndentFunc,
|
|
_indentStack = {}
|
|
}
|
|
|
|
if(style == "tab") then
|
|
proxy._indentStr = "\t"
|
|
elseif(style == "space") then
|
|
proxy._indentStr = string.rep(" ", numSpaces)
|
|
else
|
|
error("Unknown indent style " .. style)
|
|
end
|
|
|
|
setmetatable(proxy, metatable)
|
|
|
|
return proxy
|
|
end
|
|
|
|
return { TabbedFile = TabbedFile } |