Module:ExtractSection

From JoJo's Bizarre Encyclopedia - JoJo Wiki
Jump to navigation Jump to search

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

local p = {}

-- Helper function to extract content under a specific section header
function p.extractSection(content, header, strict)
    -- Define the pattern to find the section header
    local patternHeader = string.gsub(header, "[%^%$%(%)%%%.%[%]%*%+%-%?]","%%%0")
    -- Find the start of the specified header
    local sectionStart, sectionEnd = mw.ustring.find(content, patternHeader .. "%s-=+%s-\n")
    -- If the section is not found, return nil
    if not sectionStart then
        return "Error: Could not find section."
    end
    -- Get section header level
    local headerLevel = mw.ustring.match(content, "=+", sectionStart)
    if not strict or strict == "" then
        headerLevel = "=" .. mw.ustring.gsub(mw.ustring.sub(headerLevel,2), "=", "=?") .. "%s*[^=]"
    end

    -- Find the next section header of equal or higher level
    local nextHeaderPattern = "\n" .. headerLevel
    local nextHeaderStart, nextHeaderEnd = mw.ustring.find(content, nextHeaderPattern, sectionEnd + 1)
    -- Extract the content until the next section header or the end of the content
    if nextHeaderStart then
        return mw.ustring.sub(content, sectionEnd + 1, nextHeaderStart - 1)
    else
        return mw.ustring.sub(content, sectionEnd + 1)
    end
end

function p.extractTab(content, label)
    local patternLabel = string.gsub(label, "[%^%$%(%)%%%.%[%]%*%+%-%?]","%%%0")
    local pattern = patternLabel .. "%s-%|"
    local pattern2 = patternLabel .. "%s-="
    local matchStart, matchEnd = string.find(content, pattern)
    if not matchStart then
        matchStart, matchEnd = string.find(content, pattern2)
        if not matchStart then
        	mw.log(pattern)
        	mw.log(pattern2)
            return "Error: Could not find matching tab."
        end
    end

    local tab = ""
    local braceCount = 0
    local i = matchEnd + 1
    local isNewLine = false

    while i <= #content do
        local char = content:sub(i, i)

        if char == '{' then
            braceCount = braceCount + 1
        elseif char == '}' then
            braceCount = braceCount - 1
            if braceCount < 0 then
                return tab
            end
        end

        if braceCount == 0 and char == '\n' then
            isNewLine = true
            tab = tab .. char
        elseif isNewLine and char == '|' then
            break
        else
            isNewLine = false
            tab = tab .. char
        end

        i = i + 1
    end

    return tab
end

function p.transclude(frame)
    local args = frame.args
    local content = args[1]
    local field = args[2]
    local section = args.section
    local mode = args.mode
    local strict = args.strict

    local content = mw.title.new(content):getContent()
    if not content then
        return "Error: Page not found"
    end

    local redirectTarget = mw.ustring.match(content, "#REDIRECT%s-%[%[([^%]]-)%]%]")
    while redirectTarget and redirectTarget ~= "" do
        content = mw.title.new(redirectTarget):getContent()
        if not content then
            return "Error: Page not found"
        end

        redirectTarget = mw.ustring.match(content, "#REDIRECT%s-%[%[([^%]]*?)%]%]")
    end
    
    if section and section ~= "" then
        mw.log("Section found")
        content = p.extractSection(content, section, strict)
    else
        if not mode or mode ~= "tab" then
            content = p.extractSection(content, field, strict)
        end
    end

    if mode and mode == "tab" then
    	    if not (content and field) then
        		return "Error: Missing parameters."
			else
        		content = p.extractTab(content, field)
        	end
    end

    return frame:preprocess(content)
end

return p