跳转到内容

模組:Routemap/sandbox

维基百科,自由的百科全书

这是本页的一个历史版本,由Sameboat留言 | 贡献2013年12月18日 (三) 01:46编辑。这可能和当前版本存在着巨大的差异。

local i18n = {
    errors = {
        ["parameter-missing"] = "缺失參數",
        ["collapsible-block-not-closed"] = "摺疊部分未封閉",
        ["collapsible-block-not-open"] = "摺疊部分無法展開可能是由於多餘的關閉命令",
        ["too-many-parameters"] = "參數過剩",
        ["no-icons"] = "未有指定圖標",
        ["colspan-too-many-to-span"] = "colspan無法整合字串",
        ["unknown-keyword"] = "不明參數«%s»",
        ["invalid-keyword-at-position"] = "錯誤位置導致參數«%s»無效",
        ["no-collapsible-block-and-alt-syntax"] = "不兼容摺疊功能"
    },
    misc = {
        ["keyword-any"] = "''任意''"
        },
    ["error-categories"] = {
        default = '[[Category:Wikipedia:條目存在參數錯誤的線路圖]]'
        --["parameter-missing"] = '[[Category:Wikipedia:條目存在缺失參數的線路圖]]'--特定錯誤分類
    },
    html = {
        ["cell-icon-fmt"] = '\
|style="width:20px"|[[File:BSicon_%s.svg|20px|link=%s|alt=]]',
        ["cell-overlapicon-fmt"] = '<div style="position:absolute;left:0px;top:0px;padding:0">[[File:BSicon_%s.svg|20px|link=%s|alt=]]</div>',
        ["cell-icon-fmt-with-overlap"] = '\
|style="width:20px"|<div style="position:relative;width:20px">\
%s[[File:BSicon_%s.svg|20px|link=|alt=]]</div>',
        ["row-info3-fmt"]='<span style="font-size:90%%;padding-left:3px">%s</span>',
        ["row-info4-fmt"]='<div style="font-size:90%%;padding-left:3px;float:right">%s</div>',
 
        ["row-general-fmt"] = '\
|-\
|style="padding:0;white-space:nowrap;background-color:%s"|<center>\
{|cellspacing="0" cellpadding="0" style="background-color:transparent;line-height:0px !important"\
|-%s\
|}</center>\
|style="text-align:right;vertical-align:middle;padding:0 3px;font-size:80%%"|%s\
|colspan="2" style="vertical-align:middle;text-align:left;width:%s"|%s',
 
        ["row-collapsible-begin-fmt"] = '\
|-\
|colspan="5" style="padding:0 !important;white-space:nowrap;background-color:%s"|\
{|class="mw-collapsible mw-%s autocollapse" cellpadding="0" cellspacing="0" style="background-color:transparent;line-height:1.2em !important;padding:0 !important;align:left !important;margin:none !important;width:100%% !important"\
|-\
|style="padding:0 !important;white-space:nowrap;text-align:center !important;width:0px !important"|\
{|cellspacing="0" cellpadding="0" style="background-color:transparent;float:none !important;margin:auto !important;width:auto !important;line-height:0px !important"\
|-%s\
|}\
|style="text-align:right;vertical-align:middle;padding:0 3px;font-size:90%%;border: 0px !important" |%s\
!style="text-align:left;vertical-align:middle;white-space:nowrap;width:100%%;padding-right:3px;border:0px !important" colspan="2" |%s',
 
        ["row-collapsible-replace-begin-fmt"] = '\
|-\
|style="text-align:left;padding:0;white-space:nowrap"|\
<div style="position:relative">\
{|align="left" cellspacing="0" cellpadding="0" style="position:absolute;bottom:0px;background-color:#f9f9f9"\
|-%s\
|}</div>\
|style="text-align:left;padding:0;white-space:nowrap;vertical-align:middle"|\
<div style="position:relative">\
{|align="left" cellspacing="0" cellpadding="0" style="position:absolute;bottom:0px;vertical-align:middle;bottom:0px;top:-15px;background-color:#f9f9f9;line-height:130%%"\
|style="text-align:right;vertical-align:middle;padding:0 3px;font-size:90%%"|%s\
!style="text-align:left;vertical-align:middle;white-space:nowrap;width:100%%;padding-right:3px;min-width:10em" colspan="2"|%s\
|}</div>',
 
        ["row-alt-fmt"] = '\
|-\
|style="text-align:right;vertical-align:middle;padding-right:3px;width:%s"|%s\
|style="padding:0;white-space:nowrap;background-color:%s;text-align:center !important;width:0px"|\
{|cellspacing="0" cellpadding="0" style="background-color:transparent;float:none !important;margin:auto !important;width:auto !important;line-height: 0px !important;padding:0 !important"\
|-%s\
|}\
|style="text-align:left;vertical-align:middle;width:%s"|<span style="padding-left:3px">%s</span>',
 
        ["row-alt-left-note-fmt"] = '<span style="font-size:90%%;padding-right:3px">%s</span>',
        ["row-alt-right-note1-fmt"] = ' <span style="font-size:90%%">%s</span>',
        ["row-collapsible-end"] = '\n|}',
        ["colspan-fmt"] = '%s\n|-\n|colspan="4" |\n%s'
        }
}
local function formaterror(key,param)
    local result=mw.ustring.format('\n|-\n|<span class="error">%s</span>',mw.ustring.format(i18n.errors[key]or tostring(key)..' %s',
        tostring(param or '')))
    title=mw.title.getCurrentTitle()
    if mw.site.namespaces[title.namespace].isContent then result=result..(i18n['errors-categories'][key]or
        i18n['errors-categories'].default or '')end
    return result
end
 
local p,q={},{}
-- Compatibility: Lua-5.0
-- Source: http://lua-users.org/wiki/SplitJoin
-- Author: http://lua-users.org/wiki/PhilippeLhoste
local function Split(str, delim, maxNb)
    if delim==nil or delim=='' then error('bad argument #2 to \'Split\' (non-empty string expected), got '..type(delim),1)end
    if str=='' or 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
local function cell(icon,overlapIcons)
--Icon handling. Each icon is defined as in the following example:
--icon ID!~overlap icon ID!@image link target
--No limit on overlap icons, just separate them by "!~".
    local tmp,link={},''
    if #overlapIcons>0 then
        tmp=Split(overlapIcons[#overlapIcons],'!@',2)
        overlapIcons[#overlapIcons]=tmp[1]
        if #tmp==2 then link=tmp[2] end
        tmp={}
        for i,v in ipairs(overlapIcons) do
            if i==#overlapIcons then local link=link else local link='' end
            table.insert(tmp,mw.ustring.format(i18n.html['cell-overlapicon-fmt'],mw.text.trim(v),link))end
        return mw.ustring.format(i18n.html['cell-icon-fmt-with-overlap'],mw.text.trim(table.concat(tmp)),icon)
    end
    tmp=Split(icon,'!@',2)
    icon=mw.text.trim(tmp[1])
    if #tmp==2 then link=tmp[2] end
    return mw.ustring.format(i18n.html['cell-icon-fmt'],icon,link)
end
local function row(pattern,collapse)
--Row handling. Each row looks like the following:
--(icon pattern)~~info 1~~info 2~~note 1~~note 2(row properties)
--where "(row properties)" is a combination of properties with following syntax:
--!~property name=value
--Currently only "bg" (background color) and "width" are used for regular — not collapsible — rows.
    local rowProp={
        ['bg'] = 'transparent',
        ['width'] = 'auto',
        qqx={}
    }
    local info,icons,color={}
    local cells,overlapIcons,tmp={},{},Split(pattern,'~~',5)
    if #tmp>1 then rowProp.qqx=Split(tmp[#tmp],'!~')end
    if #rowProp.qqx>1 then
        tmp[#tmp]=rowProp.qqx[1]
        table.remove(rowProp.qqx,1)
        for i,v in ipairs(rowProp.qqx)do if v~='' then
            local t=Split(v,'=',2)
            rowProp[t[1]]=t[2]or ''
            end
        end
    end
    if #tmp>2 then
        info[1]=tmp[2]or''
        info[2]=tmp[3]or''
        if #tmp>3 then info[2]=info[2]..mw.ustring.format(i18n.html['row-info3-fmt'],tmp[4])end
        if #tmp>4 then info[2]=info[2]..mw.ustring.format(i18n.html['row-info4-fmt'],tmp[5])end
    else--assume only info2 was provided.
        info[1]=''
        info[2]=tmp[2]or''
    end
    icons=Split(tmp[1],'\\')
    for i,v in ipairs(icons)do
        tmp=Split(v,'!~')
        icons[i]=tmp[1]
        table.remove(tmp,1)
        table.insert(overlapIcons,tmp)
    end
    if #icons+#overlapIcons<1 then return formaterror('no-icons')end
    info[1]=mw.getCurrentFrame():preprocess(info[1])--expand possible templates in info.
    info[2]=mw.getCurrentFrame():preprocess(info[2])
    for i,v in ipairs(icons)do table.insert(cells,cell(v,overlapIcons[i]))end
    cells=table.concat(cells)
    if type(collapse)=='string' then
        return mw.ustring.format(i18n.html["row-collapsible-begin-fmt"],rowProp['bg'],collapse,cells,info[1],info[2])elseif collapse==true
            then return mw.ustring.format(i18n.html['row-collapsible-replace-begin-fmt'],cells,info[1],info[2])
                else return mw.ustring.format(i18n.html['row-general-fmt'],rowProp['bg'],cells,info[1],rowProp['width'],info[2])end
end
 
local function row2(pattern)--no collapsibles yet
--Row handling. Each row looks like the following:
--leftmost text! !(icon pattern)~~rightmost text~~note 1~~note2(row properties)
--where "(row properties)" is a combination of properties with following syntax:
--!~property name=value
--Currently used are "bg" (background color), "width-left" and "width-right".
    local rowProp={
        ['bg'] = 'transparent',
        ['width-right'] = 'auto',
        ['width-left'] = 'auto',
        qqx={}
    }
    local info,icons,color,left,right={}
    local cells,overlapIcons,tmp={},{},Split(pattern,'! !',2)
    if #tmp>1 then
        left=tmp[1]
        right=tmp[2]
    else
        left=''
        right=tmp[1]or ''
    end
    tmp=Split(right,'~~',4)
    if #tmp>1 then rowProp.qqx=Split(tmp[#tmp],'!~')end
    if #rowProp.qqx>1 then
        tmp[#tmp]=rowProp.qqx[1]
        table.remove(rowProp.qqx,1)
        for i,v in ipairs(rowProp.qqx)do if v~='' then
            local t=Split(v,'=',2)
            rowProp[t[1]]=t[2]or ''
            end
        end
    end
    if #tmp>1 then--parse right side.
        info.right=tmp[2]
        if #tmp>2 then info.right=info.right..mw.ustring.format(i18n.html['row-alt-right-note1-fmt'],tmp[3])end
        if #tmp>3 then info.right=info.right..mw.ustring.format(i18n.html['row-info4-fmt'],tmp[4])end
    else--assume only right text was provided.
        info.right=tmp[2]or''
    end
    icons=Split(tmp[1],'\\')
    for i,v in ipairs(icons)do
        tmp=Split(v,'!~')
        icons[i]=tmp[1]
        table.remove(tmp,1)
        table.insert(overlapIcons,tmp)
    end
    if #icons+#overlapIcons<1 then return formaterror('no-icons')end
    tmp=Split(left,'~~',2)--parse left side.
    if #tmp>1 then
        info.left=tmp[2]--left note
        info.left=mw.ustring.format(i18n.html['row-alt-left-note-fmt'],tmp[1])..info.left--left text
    else--assume only left text was provided
        info.left=tmp[1]or''
    end
    info.left=mw.getCurrentFrame():preprocess(info.left)--expand possible templates in info.
    info.right=mw.getCurrentFrame():preprocess(info.right)
    for i,v in ipairs(icons)do table.insert(cells,cell(v,overlapIcons[i]))end
    cells=table.concat(cells)
    return mw.ustring.format(i18n.html['row-alt-fmt'],rowProp['width-left'],info.left,rowProp['bg'],cells,
        rowProp['width-right'],info.right)
end
 
q={'startCollapsible','collapsibleReplace','colspan',collapsible=0}
q.isKeyword=function(pattern,i,rows,justTest)
    local tmp=Split(pattern,'-')
    if #tmp<2 or tmp[2]=='' or tmp[1]>'' then
        if justTest then return false else return nil end--not a valid keyword
    end
        table.remove(tmp,1)--delete first, empty part before "-"
        if type(q[tmp[1]])=="function" and tmp[1]~='isKeyword' then--valid keyword
            if justTest then return true else return q[tmp[1]](tmp,i,rows)end
            else if justTest then return false else return formaterror('unknown-keyword',tmp[1])end
        end
end
q['startCollapsible']=function(params,i,rows,alt)
    table.remove(rows,i)
    if alt then return formaterror('no-collapsible-block-and-alt-syntax')end
    if i>#rows-3 then return formaterror('collapsible-block-not-closed')end--not enough lines to close the collapsible block
    if q.isKeyword(rows[i],i,rows,true)then
        return formaterror('invalid-keyword-at-position',i18n.misc['keyword-any'])end--no valid keywords that can follow "startCollapsible" yet
    local param1,param2=params[2]or '',params[3]or 0--params[1] is the keyword name so all indices are shifted by one.
    q.collapsible=q.collapsible+1
    local result
    if param1=='' then param1='collapsed' end
    if param2~=0 then
        result=row(rows[i],param1)
        result=result..row(rows[i+1],true)
        table.remove(rows,i)
        return result
    else return row(rows[i],param1)end
end
q['endCollapsible']=function(params,i,rows,alt)
    if q.collapsible>0 then
        q.collapsible=q.collapsible-1
        return i18n.html['row-collapsible-end']
    else return formaterror('collapsible-block-not-open')end
end
q['colspan']=function(params,i,rows,alt)
    local tmp,j,param1={},0
    if params[2]=='end' then return '<!-- -colspan-end -->' else param1=tonumber(params[2])end
    table.remove(rows,i)
    if param1==nil then param1=#rows-i+1 end
    while j<param1 and i<=#rows do
        j=j+1
        local result=q.isKeyword(rows[i],i,rows)
        if type(result)~="string" then table.insert(tmp,rows[i])elseif result=='<!-- -colspan-end -->' then
            j=param1
        else table.insert(tmp,result)end
        if param1~=j or i==#rows then table.remove(rows,i)end
    end
    if j<param1 then j=formaterror('colspan-too-many-to-span') else j='' end
    return mw.ustring.format(i18n.html['colspan-fmt'],j,mw.getCurrentFrame():preprocess(table.concat(tmp,'\n')))
end
 
function p.route(frame)
-- ВАЖНО: параметр «pattern» должен быть следующего вида:
--  иконки!~перекрывающая иконки\(ещё)\(если надо, то ещё и т. д.)~~время~~текст~~пояснение~~пояснение мелким шрифтом\n
--  (другая строка таблицы в этом формате)\n(и так далее)
-- ВАЖНО: если вам нужен текст слева от иконок, то параметр «pattern» должен быть следующего вида:
--  текст слева! !иконки!~перекрывающая иконка\(ещё)\(если надо, то ещё и т. д.)~~текст справа~~пояснение справа\n
--  (другая строка таблицы в этом формате)\n(и так далее)
    local rows,tmp,alt,func={},{},false,row
    rows=Split(frame.args['pattern'],'\n')
    if mw.text.trim(table.concat(rows))=='' then return formaterror('parameter-missing')end
    if frame.args['alt']=='1' then
        func=row2
        alt=true
        end
    for i,v in ipairs(rows)do
        local keyword=q.isKeyword(v,i,rows,alt)
        if type(keyword)~="string" then table.insert(tmp,func(v,nil))else table.insert(tmp,keyword)end
    end
    if q.collapsible>0 then table.insert(tmp,formaterror('collapsibe-block-not-closed')..q['endCollapsible']())end
    return table.concat(tmp)
end
 
return p