As a newcomer, I’ve been pasting a lot of other people’s code into Codea, and what I need is something that will break out the classes and put them in tabs. I couldn’t find anything, so I wrote a utility that does it. This is how it works.
- put the code below in its own project (which I’ll call CodeSplitter for convenience). You only need to do this once.
- create a new project and paste the code you want to import, into Main as usual
- open CodeSplitter, set the name in line 9 to the name of your new project, and run it
- go back to your project, and hopefully it looks beautiful
I haven’t tested it exhaustively, but it seems to be working correctly, even if the Main code is tucked away between classes. I am fully expecting that someone will tell me there is already a much better utility to do this, but that’s life.
--Main
--[[
CodeSplitter version 1.0 March 2013 by Ignatz
This utility splits the class code in a project into separate tabs
To use it, create a new project and paste all the code into the Main tab
Put the name of the project in below and run
--]]
function setup()
SplitCode("PasteData") -- < name of your project goes in here
end
function SplitCode(nam)
--get total code
local txt=readProjectTab(nam..":Main")
--initialise, see below
local prevClassName,prevIndex="",1
local str
--it is quite difficult to find the start of a class, if you want to include
--any preceding comments
--this utility uses the fact that all classes end with a function, which in turn ends with "end"
--so it splits the entire code into chunks, all of which end with a line feed followed by "end"
local s="\
end" --the text we'll split on
local f=split(txt,s) --split using function underneath
for i=1,#f do --loop through chunks
if i<#f then f[i] = f[i]..s end --the act of splitting deleted the "end" text, put it back
c=f[i]:match("(%w+) ?= ?class") --this regex finds the class name
if c==nil then
local x= f[i]:find("function setup")
if x~=nil then c="Main" end --this regex looks for the Main tab via setup
end
--if there is a classname, then the functions from here on belong to it - until we hit the
-- next classname or the end
--the functions preceding this chunk belong to the previous class, whose name we have cunningly
--stored. For the first one, we have set it to Main
if c~=nil then
str="" --concatenate all the chunks since the previous class was written
for j=prevIndex,i-1 do
str=str..f[j]
end
str=str:match( "^%s*(.+)" ) --remove leading white space
saveProjectTab(nam..":"..prevClassName,str) --write them to a tab
prevClassName=trim(c)
prevIndex=i
end
end
--finish off the remaining text, which belongs to the last classname we have stored
if prevClassName~=nil then
str=""
for j=prevIndex,#f do
str=str..f[j]
end
str=str:match( "^%s*(.+)" ) --remove leading white space
saveProjectTab(nam..":"..prevClassName,str)
end
print("All done!")
end
function trim(s)
return s:match("^%s*(.-)%s*$")
end
-- Compatibility: Lua-5.0
--http://lua-users.org/wiki/SplitJoin
function split(str, delim, maxNb)
if maxNB==nil then maxNB=9999999 end
-- Eliminate bad cases...
if string.find(str, delim) == nil then
return { str }
end
if maxNb == nil or maxNb < 1 then
maxNb = 0 -- No limit
end
local result = {}
local pat = "(.-)" .. delim .. "()"
local nb = 0
local lastPos
for part, pos in string.gfind(str, pat) do
nb = nb + 1
result[nb] = part
lastPos = pos
if nb == maxNb then break end
end
-- Handle the last field
if nb ~= maxNb then
result[nb + 1] = string.sub(str, lastPos)
end
return result
end