Utility: organize your pasted code into class tabs

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

I am fully expecting that someone will tell me there is already a much better utility to do this, but that’s life.

There is. It’s built in to Codea. If you export the code correctly (using the copy-project-to-clipboard) then when you import it it will be split into tabs.

The syntax is not hard to emulate. Simply put --# TabName.lua before each tab chunk.

Where is the copy project to clipboard option? I press and hold on the project name and see Copy, Duplicate or Delete. If I press Copy, paste it somewhere else and then paste it back later, it does not organise itself into tabs.

Also, none of the projects I have ever imported have organised themselves into classes, so I am mystified.

As long as the codeoted has the prefix, this works as Andrew stated. I’ve done both, and have gotten tabbed code to work.

That said, there’s plenty of I tabbed code out there.

I guess the main problem is that an awful lot of code out there is not tagged, so this utility is useful (for me at least). I haven’t seen a single tagged project yet!

.@ignatz once you have copied your code with the long press on a project, do again a long press on the “+” project: paste in project will appear, and then you’m get your tabs. It is true that this does not work with many already posted projects, because it is (i guess) a 1.5 feature, so recent.

Wow, thank you for that, I had no idea that was there.

No wonder nobody uses it.