Skip to content

Instantly share code, notes, and snippets.

@SquidDev
Last active August 29, 2015 14:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SquidDev/ebd1c11dfeb1c7abe38a to your computer and use it in GitHub Desktop.
Save SquidDev/ebd1c11dfeb1c7abe38a to your computer and use it in GitHub Desktop.
Pre-Processor Imports - combine multiple files into one (http://www.computercraft.info/forums2/index.php?/topic/18959-ppi-pre-processor-includes/)

To Use

Run Combiner.lua <Initial File> <Output File> [-l] in the shell.

The -l flag defines all named requirements as local instead of global.

  • --@require whatIWantToRequire.lua to include files (or --@import whatIWantToRequire.lua)
  • --@name RandomName to give this module an alias.
  • --@include whatIWantToInclude.lua to include the source of a file where this annotation is.

More info on the forums (http://www.computercraft.info/forums2/index.php?/topic/18959-ppi-pre-processor-includes/)

local Args = {...} --Read Args
local Files = { } --All Files to include
local OutHandle = nil --File Handle to write to
local getDir = fs.getDir or function(str)
return str:match("(.*/)")
end
local UseLocals = false
for _, v in ipairs(Args) do
if v=="-l" then
UseLocals = true
end
end
--Basic error functions
local function PrintError(Message, ...)
printError(string.format(Message, unpack({...})))
end
local function Error(Message, ...)
error(string.format(Message, unpack({...})))
end
--Require and load
local RequireFile
--File functions
local function LoadFile(Path)
--Read the file
local File = fs.open(Path, "r")
if not File then
Error("Could not find %s", Path)
end
local Dir = getDir(Path)
local ThisFile = {
Path = Path,
Dir = Dir
}
Files[Path] = ThisFile
local Line = File.readLine()
local Contents = ""
while Line ~= nil do
local Annotation = Line:gmatch("%-%-@[^\n]*")()
if Annotation == nil then
Contents = Contents .. Line .. "\n"
else
Annotation = Annotation:sub(4)
local Index = Annotation:find("%s")
if not Index then
Error("Failed to execute Annotation for File '%s'", File.Path)
end
local AnnotationName = Annotation:sub(1, Index - 1)
if AnnotationName == "require" or Annotation == "import" then
local RequirePath = Annotation:sub(Index + 1):gsub("%s", "")
if not RequirePath then
Error("Failed to execute '%s' for file '%s' (missing a file path)", AnnotationName, Path)
end
RequirePath = fs.combine(Dir, RequirePath)
if Files[RequirePath] == nil then
RequireFile(RequirePath)
end
elseif AnnotationName == "name" then
local AliasName = Annotation:sub(Index + 1):gsub("%s", "")
if not AliasName then
Error("Failed to execute 'name for file '%s' (missing a name)", Path)
end
ThisFile.Alias = AliasName
elseif AnnotationName == "include" then
local IncludePath = Annotation:sub(Index + 1):gsub("%s", "")
if not IncludePath then
Error("Failed to execute 'include' for file '%s' (missing a file path)", Path)
end
IncludePath = fs.combine(Dir, IncludePath)
local IncludeFile = Files[IncludePath]
if IncludeFile == nil then
IncludeFile = LoadFile(IncludePath)
end
Contents = Contents .. "--" .. IncludePath .. "\n" .. IncludeFile.Contents
else
PrintError("Unknown annotation '%s' in file '%s'", AnnotationName, Path)
end
end
Line = File.readLine()
end
File.close()
ThisFile.Contents = Contents
return ThisFile
end
function RequireFile(Path)
local File = LoadFile(Path)
OutHandle.writeLine("--"..Path)
if File.Alias == nil then
OutHandle.writeLine("do")
OutHandle.write(File.Contents)
OutHandle.writeLine("end")
else
local Line = File.Alias .. "=_W(function()"
if UseLocals then
Line = "local "..Line
end
OutHandle.writeLine(Line)
OutHandle.writeLine(File.Contents)
OutHandle.writeLine("end)")
end
end
OutHandle = fs.open(fs.combine(shell.dir(), Args[2]), "w")
OutHandle.write([[
local function _W(f)
local m={}
setmetatable(m, {__index = getfenv()})
setfenv(f,m)
local t=f()
for k,v in pairs(m) do
t[k] = v
end
return t
end
]])
OutHandle.writeLine(LoadFile(fs.combine(shell.dir(), Args[1])).Contents)
OutHandle.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment