Srish Agrawal a écrit :
Hello EveryBody

I needed a small LUA script to be used with SciTE. It was supposed to remove all
multilple lines except the first one from a text document without changing the
original document in any other way. Unable to find a similer script posted
anywhere on the NET, I wrote it myself.
Of cource, I borrowed some coding ideas/tricks and functions from codes written
by Neil Hodgson and Philippe Lhoste.

It works as expected but is rather big.  May anybody give me some idea as to how
can I cange the logic and save a few lines of code.

This is what I have :

-- this function removes multiple lines
-- only the first occurance is kept
-- original order of lines are meintained
-- NOTE
-- editor line number starts from ZERO
-- table element number strats from ONE

function RemoveDupLines()
    local t = {}                -- // table in which all the editor lines are 
stored
    local t1 = {}               -- // table in which unique elements of t are 
stored
    local t2 = {}               -- // for temp storage of multiple lines
    local t3 = {}
    local eol = GetEOL()
    local en = editor.LineCount -- // number of lines in editor
    local dup_below = 0         -- // current line is not dup with line below it

    for i = 0, en-1 do
        local line = editor:GetLine(i)
        -- knock off eol
        line = trimR(line)
        -- eliminate blank lines
        if line ~= ""  and  line ~= nil then
            -- Store line number and the line
            table.insert(t,{i,line})
        end
    end

    -- sort on second field
    table.sort(t, sort2)
    local tn = table.getn(t)

--[[
    print('this is the table after first sort')
    for k, v in ipairs(t) do
        print(v[1] .. '        ' .. v[2])
    end
    print("-----------------")
]]

    -- in the sorted table, equal lines have been bundled together
    -- but they may not be in the same order as they were in the original
    -- document

    for i=1, tn do
        v1 = t[i][2]
        if i ~= tn then
            v2 = t[i+1][2]
        else
            v2 = ""
        end

        if v1 == v2 then
            dup_below = 1
        else
            dup_below = 0
        end

        if i == 1 and dup_below == 0 then
            table.insert(t1, {t[i][1], t[i][2]})
        elseif dup_below == 1 then
            table.insert(t2, {t[i][1], t[i][2]})
        elseif dup_below == 0 and table.getn(t2) > 0 then
            table.insert(t2, {t[i][1], t[i][2]})
            table.sort(t2, sort1)
            table.insert(t1, {t2[1][1], t2[1][2]})

--[[
            print('this is the temp table for dup lines')
            for k, v in ipairs(t2) do
                print(v[1] .. '        ' .. v[2])
            end
            print("-----------------")
]]

            -- requirement of t2 is over flush it
            local t2n = table.getn(t2)
            for j = 1,t2n do
                table.remove(t2, j)
            end
        else
            table.insert(t1, {t[i][1], t[i][2]})
        end
    end

--[[
    print('this is the table after removing multiple lines')
    for k, v in ipairs(t1) do
        print(v[1] .. '        ' .. v[2])
    end
    print("-----------------")
]]

    -- sort on first field because
    -- we want to maintain original order of lies
    table.sort(t1, sort1)
    for k, v in ipairs(t1) do
        table.insert(t3, v[2])
    end
    local s = table.concat(t3, eol)
    editor:SetText(s)

--[[
    print('and this is the final result')
    for k, v in ipairs(t1) do
        print(v[1] .. '        ' .. v[2])
    end
    print("-----------------")
]]

end
function sort1(el1, el2)
        if el1[1] < el2[1] then
        return el1
    end
end
function sort2(el1, el2)
    if el1[2] < el2[2] then
        return el1
    end
end

function trimR (str)
    if str ~= ""  and  str ~= nil then
        while true do
            if str ~= ""  and  str ~= nil then
                local len = string.len(str)
                if string.sub(str,len) == '\r' then
                    str = string.sub(str,1,len-1)
                elseif string.sub(str,len) == '\n' then
                    str = string.sub(str,1,len-1)
                else
                    break
                end
             else
                break
            end
        end
    end
    return str
end

function GetEOL()
        local eol = "\r\n"
        if editor.EOLMode == SC_EOL_CR then
                eol = "\r"
        elseif editor.EOLMode == SC_EOL_LF then
                eol = "\n"
        end
        return eol
end

I have no time to look into it right now, but I give a little improvement of your trimR function: see this little code sample:

testString = "Foo Bar\r\n"
finalString = string.gsub(testString, "^([^%c]*)%c*", "%1")
print(">" .. testString .. "<")
print(">" .. finalString .. "<")

Works even on empty string...

Will take a closer look later.


--
Philippe Lhoste
--  (near) Paris -- France
--  http://Phi.Lho.free.fr
--  --  --  --  --  --  --  --  --  --  --  --  --  --

_______________________________________________
Scite-interest mailing list
[email protected]
http://mailman.lyra.org/mailman/listinfo/scite-interest

Reply via email to