Module:Extract

From Bahaiworks

Documentation for this module may be created at Module:Extract/doc

local p = {}

local function _main( args )
    local j, begin
    local i = 1
    local s = args[1]
    if args['end'] and not args['beginNum'] then
        begin = args['begin'] or nil
        if begin then
            i = mw.ustring.find(s, begin, 1, true)
        end
        j = mw.ustring.find(s, args['end'], i, true) - 1 + mw.ustring.len(args['end']) --Adding last portion to be inclusive
        return mw.ustring.sub(s, i, j)
    elseif args['end'] then
        begin = args['beginNum']
        if begin then
            local psc = mw.text.split(begin, '.', true)
            if psc[1] then
                local pars = tonumber(psc[1])
                if pars then
                    for k=1, pars do
                        local m = mw.ustring.find(s, '\n\n', i, true)
                        if not m then
                            break
                        end
                        i = m
                    end
                end
            end
            if psc[2] then
                local sents = tonumber(psc[2])
                if sents then
                    for k=1, sents do
                        local m = mw.ustring.find(s, '[.?!] ', i)
                        if not m then
                            break
                        end
                        i = m + 1
                    end
                end
            end
            if psc[3] then
                local chrs = tonumber(psc[3])
                if chrs then
                    i = i + chrs
                end
            end
        end
        --todo: change to handle endNum instead of end
        j = mw.ustring.find(s, args['end'], i, true) - 1 + mw.ustring.len(args['end']) --Adding last portion to be inclusive
        return mw.ustring.sub(s, i, j)
    end

    return '<span style="color:red">(No end parameter supplied)</span>'
end

function p.main(frame)
    local origArgs

    if frame == mw.getCurrentFrame() then
        -- We're being called via #invoke. If the invoking template passed any arguments,
        -- use them. Otherwise, use the arguments that were passed into the template.
        origArgs = frame:getParent().args
        for k, v in pairs( frame.args ) do
            origArgs = frame.args
            break
        end
    else
        -- We're being called from another module or from the debug console, so assume
        -- the arguments are passed in directly.
        origArgs = frame
    end

    -- Process integer args. Allow for explicit positional arguments that are
    -- specified out of order, e.g. {{br separated entries|3=entry3}}.
    -- After processing, the args can be accessed accurately from ipairs.
    local args = {}

    for k, v in pairs( origArgs ) do
        if type( k ) == 'number' and
            k >= 1 and
            math.floor( k ) == k and
            mw.ustring.match( v, '%S' ) then -- Remove blank or whitespace values.
            table.insert( args, k )
        end

    end

    table.sort( args )

    for i, v in ipairs( args ) do
        args[ i ] = origArgs[ v ]

        -- Trim whitespace.
        if type( args[ i ] ) == 'string' then
            args[ i ] = mw.text.trim( args[ i ] )
        end
    end

    if origArgs.begin and origArgs.begin ~= '' then
        args.begin = origArgs.begin
    end

    if origArgs["end"] and origArgs["end"] ~= '' then
        args["end"] = origArgs["end"]
    end
    
    if origArgs["beginNum"] and origArgs["beginNum"] ~= '' then
        args["beginNum"] = origArgs["beginNum"]
    end

    if origArgs["endNum"] and origArgs["endNum"] ~= '' then
        args["endNum"] = origArgs["endNum"]
    end

    return _main( args )
end

return p