コンテンツにスキップ

英文维基 | 中文维基 | 日文维基 | 草榴社区

利用者:Burthsceh/サンドボックス/モジュール:TranscludeSection

--

local p = {}
local r = {
    [2] = "\n(==)[^=\n][^\n]-%f[=]%1%s*%f[%z\n]",
    [3] = "\n(===?)[^=\n][^\n]-%f[=]%1%s*%f[%z\n]",
    [4] = "\n(===?=?)[^=\n][^\n]-%f[=]%1%s*%f[%z\n]",
    [5] = "\n(===?=?=?)[^=\n][^\n]-%f[=]%1%s*%f[%z\n]",
    [6] = "\n(===?=?=?=?)[^=\n][^\n]-%f[=]%1%s*%f[%z\n]",
}

local function patternescape(pattern)
    return pattern:gsub("[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0")
end

local trim = mw.text.trim

-- use {{#lsth:page|section}}
function p.select(frame, args)
    args = args or ((frame.args[1] or frame.args.page) and frame.args) or frame:getParent().args
    local page = args[1] or args.page
    local section = args[2] or args.section
    local text = mw.title.new(page):getContent()
    
    if not page or not section or not text then
        return ""
    end
    
    section = patternescape(section)
    
    local s, e, h = text:find("^(===?=?=?=?)%s*" .. section .. "%s*%1%s*%f[%z\n]")
    if not s then
        s, e, h = text:find("\n(===?=?=?=?)%s*" .. section .. "%s*%1%s*%f[%z\n]")
    end
    if not s then
        return ""
    end
    
    -- s = text:find("\n(==" .. ("=?"):rep(#h - 2) .. ")[^=\n][^\n]-%f[=]%1%s*%f[%z\n]", e)
    s = text:find(r[#h], e)
    
    return frame:preprocess(trim(text:sub(e + 1, (s or 0) - 1)))
end

function p.selectignorelevel(frame, args)
    args = args or ((frame.args[1] or frame.args.page) and frame.args) or frame:getParent().args
    local page = args[1] or args.page
    local section = args[2] or args.section
    local text = mw.title.new(page):getContent()
    
    if not page or not section or not text then
        return ""
    end
    
    section = patternescape(section)
    
    local s, e = text:find("^(===?=?=?=?)%s*" .. section .. "%s*%1%s*%f[%z\n]")
    if not s then
        s, e = text:find("\n(===?=?=?=?)%s*" .. section .. "%s*%1%s*%f[%z\n]")
    end
    if not s then
        return ""
    end
    
    s = text:find(r[6], e)
    
    return frame:preprocess(trim(text:sub(e + 1, (s or 0) - 1)))
end

-- use {{#lsth:page|start|e}}
function p.selectrange(frame, args)
    args = args or ((frame.args[1] or frame.args.page) and frame.args) or frame:getParent().args
    local page = args[1] or args.page
    local start = args[2] or args.start
    local e = args[3] or args["end"]
    local text = mw.title.new(page):getContent()
    
    if not page or not start or not e or not text then
        return ""
    end
    
    start = patternescape(start)
    e = patternescape(e)
    
    local ss, se = text:find("^(===?=?=?=?)%s*" .. start .. "%s*%1%s*%f[%z\n]")
    if not ss then
        ss, se = text:find("\n(===?=?=?=?)%s*" .. start .. "%s*%1%s*%f[%z\n]")
    end
    if not ss then
        return ""
    end
    
    local es = text:find("^(===?=?=?=?)%s*" .. e .. "%s*%1%s*%f[%z\n]", se)
    if not es then
        es = text:find("\n(===?=?=?=?)%s*" .. e .. "%s*%1%s*%f[%z\n]", se)
    end
    
    return frame:preprocess(trim(text:sub(se + 1, (es or 0) - 1)))
end

-- use {{#lsth:page|}}
function p.top(frame, args)
    args = args or ((frame.args[1] or frame.args.page) and frame.args) or frame:getParent().args
    local page = args[1] or args.page
    local text = mw.title.new(page):getContent()
    
    if not page or not text then
        return ""
    end
    
    local s = text:find("^(===?=?=?=?)[^=\n][^\n]-%f[=]%1%s*%f[%z\n]")
    if not s then
        s = text:find(r[6])
    end
    
    return frame:preprocess(trim(text:sub(e + 1, (s or 0) - 1)))
end

local function gettext(section,text,heading,link,frame)
    section["end"] = section["end"] or #text
    if section.start > section["end"] then
        return nil
    end
    
    local t = text:sub(section.start, section["end"])
    if #t == 0 then
        return nil
    end
    t = trim(t)
    if #t == 0 then
        return nil
    end
    t = frame:preprocess(t)
    if #t == 0 then
       return nil
    end
    
    if heading and section.name then
        if r[heading] then
            heading = ("="):rep(heading)
        else
            heading = section.h
        end
        
        if not link then
            return heading .. section.name .. heading .. "\n" .. t
        end
        if #link > 0 then
            return heading .. "[[" ..link .. "|" .. section.name .. "]]" .. heading .. "\n" .. t
        else
            return heading .. "[[" .. section.name .. "]]" .. heading .. "\n" .. t
        end
    end
    
    return t
end

function p.backifempty(frame, args)
    args = args or ((frame.args[1] or frame.args.page) and frame.args) or frame:getParent().args
    local page = args[1] or args.page
    local section = args[2] or args.section
    local heading = args.heading
    local link = args.link
    local text = mw.title.new(page):getContent()
    local sections = {
        [0] = {
            name = nil,
            start = 1,
            ["end"] = false,
        }
    }
    local searchlimit = 100
    
    if not page or not section or not text then
        return ""
    end
    
    local s, e, h, sec = text:find("^(===?=?=?=?)([^=\n][^\n]-%f[=])%1%s*%f[%z\n]")
    if s then
        sections[0]["end"] = 0
        sections[1] = {
            name = sec,
            start = e + 1,
            ["end"] = false,
        }
        if sec == section then
            sections[1].h = h
            sections[1]["end"] = text:find(r[6], e)
            local t = gettext(sections[1], text, heading, link, frame)
            t = t or gettext(sections[0], text, heading, link, frame)
            return t or ""
        end
    end
    
    for i = #sections + 1, searchlimit do
        s, e, h, sec = text:find("\n(===?=?=?=?)([^=\n][^\n]-%f[=])%1%s*%f[%z\n]", e)
        if not s then
            break
        end
        sections[i - 1]["end"] = s
        sections[i] = {
            name = sec,
            start = e + 1,
            ["end"] = false,
        }
        if sec == section then
            sections[i].h = h
            sections[i]["end"] = text:find(r[6], e)
            break
        end
    end
    
    for i = #sections, 0, -1 do
        local t = gettext(sections[i], text, heading, link, frame)
        if t then
            return t
        end
    end
    
    return ""
end

return p
--