跳转到内容

模組:Taxobox/Sandbox

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

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

--
-- This module implements {{Taxobox}}
--

local p = {}

local HtmlBuilder = require('Module:HtmlBuilder')
local Symbol = require('Module:TaxoboxSymbol')

local backgroundColor = '#F9F9F9'
local args = {}
local origArgs
local root

local function preprocessSingleArg(argName)
    -- If the argument exists and isn't blank, add it to the argument table.
    -- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
    if origArgs[argName] and origArgs[argName] ~= '' then
        args[argName] = origArgs[argName]
    end
end

local function preprocessArgs(mainArg, subArgsTable, step)
    if not mainArg then return end
    if type(subArgsTable) ~= 'table' then
        error("Non-table value detected for the subArgsTable table", 2)
    end
    if type(step) ~= 'number' then
        error("Invalid step value detected", 2)
    end

    -- Add postfix 1 to argument
    if origArgs[mainArg] then
        origArgs[mainArg .. '1'] = origArgs[mainArg]
    end
    for i, v in ipairs(subArgsTable) do
        local argName = mainArg .. '_' .. v
        if origArgs[argName] then
            origArgs[mainArg .. '1_' .. v] = origArgs[argName]
        end
    end

    for i = 1, step do
        local prefixArgName = mainArg .. tostring(i)
        preprocessSingleArg(prefixArgName)
        for j, v in ipairs(subArgsTable) do
            local argName = prefixArgName .. '_' .. v
            if origArgs[argName] then
                preprocessSingleArg(argName)
            end
        end
    end
end

local function getArgNums(prefix)
    -- Returns a table containing the numbers of the arguments that exist
    -- for the specified prefix. For example, if the prefix was 'data', and
    -- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.
    local nums = {}
    for k, v in pairs(args) do
        local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
        if num then table.insert(nums, tonumber(num)) end
    end
    table.sort(nums)
    return nums
end

local function getBackgroundColor()
    return '#F9F9F9'
end

local function renderHeader()
    if not args.name then return end
 
    local header = root.tag('tr')
        .css('text-align', 'center')
        .css('background-color', backgroundColor)
        .tag('th')
            .attr('colspan', 2)
            .css('text-align', 'center')
            .done()

    header.tag('span')
        .addClass('metadata')
        .css('position', 'absolute')
        .css('right', '6px')
        .wikitext('[[File:Torchlight_help_icon.svg|16px|right|link=Wikipedia:如何讀生物分類框|如何讀生物分類框]]')
    header.wikitext(args.name)

    if args.fossil_range then
        header.tag('br').tag('small').wikitext('化石時期:' .. args.fossil_range)
    end
end

local function renderImages()
    local imagenums = getArgNums('image')
    for k, num in ipairs(imagenums) do
        local prefix = 'image' .. tostring(num)
        local data = '[[File:' .. args[prefix]

        if args[prefix .. '_width'] then
            data = data .. '|' .. args[prefix .. '_width']
        else
            data = data .. '|frameless'
        end
        if args[prefix .. '_alt'] then
            data = data .. '|alt=' .. args[prefix .. '_alt']
        end
        data = data .. ']]'

        root.tag('tr').tag('td')
            .attr('colspan', 2)
            .css('text-align', 'center')
            .wikitext(data)
        if args[prefix .. '_caption'] then
            root.tag('tr').tag('td')
                .attr('colspan', 2)
                .css('text-align', 'center')
                .css('font-size', '88%')
                .wikitext(args[prefix .. '_caption'])
        end
    end
end

local function renderConservationStatus()
    local statusnums = getArgNums('status')
    if not statusnums then return end

    local s = Symbol.conservationStatusTable

    root.tag('tr').tag('th')
        .attr('colspan', 2)
        .css('text-align', 'center')
        .css('background-color', backgroundColor)
        .wikitext('[[保护状况]]')

    for k, num in ipairs(statusnums) do
        local prefix = 'status' .. tostring(num)
        local system = (args[prefix .. '_system'] or 'default'):lower()
        local status = (args[prefix] or 'invaild'):lower()

        if not s[system] then
            system = 'default'
        elseif s[system]['alias'] then
            system = s[system]['alias']
        end
        if not s[system][status] then
            status = 'invalid'
        elseif s[system][status]['alias'] then
            status = s[system][status]['alias']
        end

        local element = root.tag('tr').tag('td')
            .attr('colspan', 2)
            .tag('div')
        if s[system][status]['photo'] then
            element
                .wikitext(s[system][status]['photo'])
                .tag('br')
        end
        element
            .css('text-align', 'center')
            .wikitext(s[system][status]['name'])
        if s[system][status]['extinct'] and args.extinct then
            element.wikitext('(' .. args.extinct .. ')')
        end

        element.tag('span')
            .css('font-size', '0.8em')
            .wikitext('(' .. (args.status_text or s[system]['introduction']) ..  ')' ..
                      (args[prefix .. '_ref'] or ''))

        if s[system][status]['category'] and mw.site.namespaces.id == 0 then
            element.wikitext('[[Category:' .. s[system][status]['category'] .. ']]')
        end
    end
end

local function renderClassification()
    local header = root.tag('tr').tag('th')
        .attr('colspan', 2)
        .css('text-align', 'center')
        .css('background-color', backgroundColor)
        .wikitext(args.virus_group and '[[病毒分類]]' or '[[科學分類]]')

    local row = root.tag('tr')
    if args.virus_group then
        root.tag('td').wikitext('组')

        args.virus_group = args.virus_group:lower()
        local text
        if args.virus_group == 'i' then
            text = 'Group I<small>([[dsDNA病毒|dsDNA]])</small>'
        elseif args.virus_group == 'ii' then
            text = 'Group II<small>([[ssDNA病毒|ssDNA]])</small>'
        elseif args.virus_group == 'iii' then
            text = 'Group III<small>([[dsRNA病毒|dsRNA]])</small>'
        elseif args.virus_group == 'iv' then
            text = 'Group IV<small>([[正義ssRNA病毒|(+)ssRNA]])</small>'
        elseif args.virus_group == 'v' then
            text = 'Group V<small>([[反義ssRNA病毒|(-)ssRNA]])</small>'
        elseif args.virus_group == 'vi' then
            text = 'Group VI<small>([[ssRNA-RT病毒|ssRNA-RT]])</small>'
        elseif args.virus_group == 'vii' then
            text = 'Group VII<small>([[dsDNA-RT病毒|dsDNA-RT]])</small>'
        else
            text = args.virus_group
        end
        root.tag('td').wikitext(text)
    end

    local c = Symbol.classificationTable
    for i = 1, #c do
        local prefix = 'unranked_' .. c[i]['argName']
        if args[prefix] then
            local row = root.tag('tr')
            row.tag('td').wikitext('(未分级)')
            local cell = row.tag('td').tag('span')
            cell
                .addClass('unranked')
                .css('white-space', 'nowrap')
                .wikitext(args[prefix])
            if args[prefix .. '_authority'] then
                cell.tag('br')
                cell.tag('small').wikitext(args[prefix .. '_authority'])
            end
        end

        prefix = c[i]['argName']
        if args[prefix] then
            local row = root.tag('tr')
            row.tag('td').wikitext(c[i]['rankName'] .. ':')
            local cell = row.tag('td').tag('span')
            cell
                .addClass(c[i]['className'] or c[i]['argName'])
                .css('white-space', 'nowrap')
                .wikitext(args[prefix])
            if args[prefix .. '_authority'] then
                cell.tag('br')
                cell.tag('small').wikitext(args[prefix .. '_authority'])
            end
        end
    end
end

local function _taxobox()
    backgroundColor = getBackgroundColor()

    root = HtmlBuilder.create('table')

    root
        .addClass('infobox')
        .addClass('biota')
        .css('text-align', 'left')
        .css('width', '200px')
        .css('font-size', '100%')

    renderHeader()
    renderImages()
    renderConservationStatus()
    renderClassification()

    return tostring(root)
end

function p.taxobox(frame)
    -- If called via #invoke, use the args passed into the invoking template.
    -- Otherwise, for testing purposes, assume args are being passed directly in.
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
    else
        origArgs = frame
    end

    -- Parse the data parameters in the same order that the old {{taxobox}} did, so that
    -- references etc. will display in the expected places. Parameters that depend on
    -- another parameter are only processed if that parameter is present, to avoid
    -- phantom references appearing in article reference lists.
    preprocessSingleArg('color')
    preprocessSingleArg('name')
    preprocessArgs('status', {'system', 'ref'}, 3)
    preprocessSingleArg('status_text')
    preprocessSingleArg('extinct')
    preprocessSingleArg('fossil_range')
    preprocessArgs('image', {'width', 'alt', 'caption'}, 3)
    preprocessSingleArg('classification_status')
    preprocessSingleArg('virus')
    preprocessSingleArg('virus_group')
    preprocessSingleArg('unranked_superdomain')
    preprocessSingleArg('unranked_superdomain_authority')
    preprocessSingleArg('superdomain')
    preprocessSingleArg('superdomain_authority')
    preprocessSingleArg('domain')
    preprocessSingleArg('domain_authority')
    preprocessSingleArg('superregnum')
    preprocessSingleArg('superregnum_authority')
    preprocessSingleArg('unranked_regnum')
    preprocessSingleArg('unranked_regnum_authority')
    preprocessSingleArg('regnum')
    preprocessSingleArg('regnum_authority')
    preprocessSingleArg('subregnum')
    preprocessSingleArg('subregnum_authority')
    preprocessSingleArg('superdivisio')
    preprocessSingleArg('superdivisio_authority')

    return _taxobox()
end

return p