模組:Taxobox/Sandbox
外观
--
-- 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 lastAuthority
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(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 preprocessClassificationArgs()
local c = Symbol.classificationTable
for i = 1, #c do
local arg = c[i]['argName']
preprocessSingleArg('unranked_' .. arg)
preprocessSingleArg('unranked_' .. arg .. '_local')
preprocessSingleArg('unranked_' .. arg .. '_authority')
preprocessSingleArg(arg)
preprocessSingleArg(arg .. '_local')
preprocessSingleArg(arg .. '_authority')
end
end
local function preprocessTypeSpeciesArgs()
local t = Symbol.typeSpeciesTable
for i = 1, #t do
local arg = 'type_' .. t[i]['argPostfix']
preprocessSingleArg(arg)
preprocessSingleArg(arg .. '_authority')
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 getClassificationEntry()
local c = Symbol.classificationTable
local entryTable = {}
for i = 1, #c do
local argName = c[i]['argName']
for j, v in ipairs({'unranked_' .. argName, argName}) do
if j == 1 then
if args[v] then
table.insert(entryTable, {
['id'] = i, ['argName'] = v, ['entryName'] = '(未分级)',
['className'] = 'unranked'})
end
else
if args[v] then
table.insert(entryTable, {
['id'] = i, ['argName'] = v, ['entryName'] = c[i]['entryName'] .. ':',
['className'] = c[i]['className'] or c[i]['argName']})
end
end
end
end
return entryTable
end
local function getBackgroundColor()
if args.color then
return args.color
end
local arg
if args.domain and args.domain:lower():find('bacteria') ~= nil then
arg = 'bacteria'
else
arg = (args.regnum or args.virus_group or args.unranked_phylum or args.unranked_phylum or
args.unranked_superdivisio or args.phylum):lower()
end
if arg:find('animal') ~= nil then
return '#d3d3a4;'
elseif arg:find('plant') ~= nil or arg:find('archaeplastida') ~= nil then
return '#90ee90;'
elseif arg:find('fungi') ~= nil or arg:find('fungus') ~= nil then
return '#add8e6;'
elseif arg:find('chromalveolata') ~= nil or arg:find('chromalveolate') ~= nil then
return '#adee3f;'
elseif arg:find('choanozoa') ~= nil or arg:find('opisthokonta') ~= nil then
return '#e0d0b0;'
elseif arg:find('rhizaria') ~= nil then
return '#e1ccfc;'
elseif arg:find('excavata') ~= nil or arg:find('excavate') ~= nil or arg:find('protist') ~= nil then
return '#f0e68c;'
elseif arg:find('amoebozoa') ~= nil then
return '#ffc8a0;'
elseif arg:find('bacteria') ~= nil or arg:find('bacterium') ~= nil or arg:find('firmicutes') ~= nil then
return '#d3d3d3;'
elseif arg:find('nanoarchaeota') ~= nil or arg:find('nanarchaeota') ~= nil or
arg:find('korarchaeota') ~= nil or arg:find('archaea') ~= nil or
arg:find('thaumarchaeota') ~= nil or arg:find('crenarchaeota') ~= nil or
arg:find('euryarchaeota') ~= nil then
return '#ecd2d2;'
elseif arg:find('incertae sedis') ~= nil then
return '#faf0e6;'
elseif arg:find('virus') ~= nil or arg == 'i' or arg == 'ii' or arg == 'iii' or
arg == 'iv' or arg == 'v' or arg =='vi' or arg == 'vii' or arg == 'viii' then
return '#ee82ee;'
else
if mw.site.namespaces.id == 0 then
root.wikitext('[[Category:未指定Taxobox模板颜色]]')
end
return 'transparent; text-align: center; border: 1px solid red;'
end
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('vertical-align', 'middle')
.css('height', '25px')
.tag('div')
.css('position', 'absolute')
.css('right', '6px')
.addClass('floatright')
.tag('span')
.addClass('metadata')
.wikitext('[[File:Torchlight_help_icon.svg|16px|alt=如何讀生物分類框|link=Wikipedia:如何讀生物分類框|如何讀生物分類框]]')
.done()
.done()
.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)
return
end
local entrys = getClassificationEntry()
for i = 1, #entrys do
local argName = entrys[i]['argName']
local entryName = entrys[i]['entryName']
local id = entrys[i]['id']
local localText = args[argName .. '_local'] or ''
if localText and i ~= #entrys then
localText = '[[' .. localText .. ']]'
end
local text = args[argName]
if tonumber(id) >= 35 then -- genus
text = '\'\'' .. args[argName] .. '\'\''
end
text = localText .. ' ' .. text
if i == #entrys then -- last entry
text = '\'\'\'' .. text .. '\'\'\''
end
local row = root.tag('tr')
row.tag('td').css('text-align', 'left').css('white-space', 'nowrap').wikitext(entryName)
local cell = row.tag('td').tag('span')
cell
.addClass(className)
.css('white-space', 'nowrap')
.wikitext(text)
if args[argName .. '_authority'] then
cell.tag('br')
cell.tag('small').wikitext(args[argName .. '_authority'])
end
end
end
local function renderNomenclature()
if args.binomial1 then
local cell = root
.tag('tr')
.tag('th')
.attr('colspan', 2)
.css('text-align', 'center')
.css('background-color', backgroundColor)
.wikitext('[[二名法]]')
.done()
.done()
.tag('tr')
.tag('td')
.attr('colspan', 2)
.css('text-align', 'center')
.tag('span')
.addClass('binomial')
.css('font-weight', 'bold')
.wikitext(args.binomial1)
.done()
if args.binomial1_authority then
cell.tag('br').tag('small').wikitext(args.binomial1_authority)
end
end
if args.trinomial1 then
local tip = '[[三名法]]'
if args.regnum and args.regnum:lower():find('plant') ~= nil or
args.regnum:lower():find('archaeplastida') ~= nil then
tip = '[[種下分類群|三名法]]'
end
local cell = root
.tag('tr')
.tag('th')
.attr('colspan', 2)
.css('text-align', 'center')
.css('background-color', backgroundColor)
.wikitext(tip)
.done()
.done()
.tag('tr')
.tag('td')
.attr('colspan', 2)
.css('text-align', 'center')
.tag('span')
.addClass('trinomial')
.css('font-weight', 'bold')
.wikitext(args.binomial1)
.done()
if args.trinomial1_authority then
cell.tag('br').tag('small').wikitext(args.trinomial1_authority)
end
end
end
local function renderTypeSpecies()
local t = Symbol.typeSpeciesTable
for i = 1, #t do
local argName = 'type_' .. t[i]['argPostfix']
if args[argName] then
local cell = root
.tag('tr')
.tag('th')
.attr('colspan', 2)
.css('text-align', 'center')
.css('background-color', backgroundColor)
.wikitext(t[i]['entryText'])
.done()
.done()
.tag('tr')
.tag('td')
.attr('colspan', 2)
.css('text-align', 'center')
.wikitext(args[argName])
.done()
if args[argName .. '_authority'] then
cell.tag('br').tag('small').wikitext(args[argName .. '_authority'])
end
end
end
end
local function renderSubdivision()
if args.subdivision then
root.tag('tr')
.tag('td')
.attr('colspan', 2)
.css('text-align', 'center')
.css('background-color', backgroundColor)
.wikitext(args.subdivision_ranks or '')
.done()
.tag('td')
.attr('colspan', 2)
.css('text-align', 'left')
.wikitext(args.subdivision)
end
if args.possible_subdivision then
root.tag('tr')
.tag('td')
.attr('colspan', 2)
.css('text-align', 'center')
.css('background-color', backgroundColor)
.wikitext(args.possible_subdivision_ranks or '')
.done()
.tag('td')
.attr('colspan', 2)
.css('text-align', 'left')
.wikitext(args.possible_subdivision)
end
end
local function renderDiversity()
if not args.diversity or not args.diversity_link then return end
root.tag('tr')
.tag('td')
.attr('colspan', 2)
.css('text-align', 'center')
.css('background-color', backgroundColor)
.wikitext('[[' .. args.diversity_link .. '|多样性]]')
.done()
.tag('td')
.attr('colspan', 2)
.css('text-align', 'center')
.wikitext(args.diversity)
if mw.site.namespaces.id == 0 then
root.wikitext('[[Cagegory:使用多样性参数的Taxobox]]')
end
end
local function renderRangeMapAndExtraNomenclature()
local prefix
for i = 1, 4 do
if i ~= 1 then
for k, name in ipairs({'binomial', 'trinomial'}) do
prefix = name .. i
if args[prefix] then
local cell = root.tag('tr').tag('td')
.attr('colspan', 2)
.css('text-align', 'center')
.wikitext('\'\'\'' .. args[prefix] .. '\'\'\'')
if args[prefix .. '_authority'] then
cell.tag('small').wikitext(args[prefix .. '_authority'])
end
end
end
end
prefix = 'range_map' .. i
if args[prefix] then
root.tag('tr').tag('td')
.attr('colspan', 2)
.css('text-align', 'center')
.wikitext('[[File:' .. args[prefix],
'|' .. (args[prefix .. '_width'] or 'frameless'),
'|alt=' .. (args[prefix .. '_alt'] or ''), ']]')
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 renderSynonyms()
if not args.synonyms then return end
root.tag('tr').tag('td')
.attr('colspan', 2)
.css('text-align', 'center')
.css('background-color', backgroundColor)
.wikitext('[[異名]]' .. (args.synonyms_ref or ''))
root.tag('tr').tag('td')
.attr('colspan', 2)
.css('text-align', 'left')
.wikitext(args.synonyms)
end
local function renderFooter()
if not args.footer then return end
root.tag('tr').tag('td')
.attr('colspan', 2)
.css('text-align', 'left')
.wikitext(args.footer)
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()
renderNomenclature()
renderTypeSpecies()
renderSubdivision()
renderDiversity()
renderRangeMapAndExtraNomenclature()
renderSynonyms()
renderFooter()
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')
preprocessClassificationArgs()
preprocessArgs('binomial', {'authority'}, 4)
preprocessArgs('trinomial', {'authority'}, 4)
preprocessTypeSpeciesArgs()
preprocessSingleArg('subdivision')
preprocessSingleArg('subdivision_ranks')
preprocessSingleArg('possible_subdivision')
preprocessSingleArg('possible_subdivision_ranks')
preprocessSingleArg('diversity')
preprocessSingleArg('diversity_link')
preprocessArgs('range_map', {'width', 'alt', 'caption'}, 4)
preprocessSingleArg('synonyms')
preprocessSingleArg('synonyms_ref')
preprocessSingleArg('footer')
return _taxobox()
end
return p