Модуль:Taxonomy/classification/песочница

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Документация
local p = {}
local Taxonomy_latin = require("Module:Taxonomy/latin")

local Rangs = { --классификация рангов
    Osn = "/Домен/Реалм/Царство/Тип/Отдел/Класс/Отряд/Порядок/Семейство/Род/Вид/Ихнород/Ихновид/", --основные
    Prom = "/Субреалм/Подцарство/Надтип/Надотдел/Подтип/Подотдел/Инфратип/Надкласс/Подкласс/Инфракласс/Надотряд/Надпорядок/Подотряд/Подпорядок/Инфраотряд/Надсемейство/Подсемейство/Надтриба/Триба/Подтриба/Раздел/Подраздел/Подрод/Надсекция/Секция/Подсекция/Ряд/Подряд/Комплекс видов/Подвид/Вариетет/Разновидность/Подразновидность/Форма/Подформа/Наддомен/", --промежуточные
    Bez = "/Группа/Клада/Без ранга/",
    Ich = "/Ихнород/Ихновид/", --ихнотаксоны
    Err = "'''???'''", --в случае, если ранг не заполнен
    Spec = "/Вид/Подвид/Вариетет/Разновидность/Подразновидность/Форма/Подформа/Ихновид/Штамм/Биовар/Биотип/Cеровар/Серотип/Изолят/" --вид и ниже
}

local RangColors = {Osn = "inherit", Prom = "#007878", Dop = "DarkRed", Bez = "#6F6F00", Ich = "DarkViolet", Err = "Red"}

local regnum

local function RangClass(rang, page) -- class=mw-collapsed для сворачивания всех неосновных рангов
    return (string.find(Rangs.Osn, '/' .. rang .. '/', 1, true) or (rang == Rangs.Err)) and '' or 'class="mw-collapsible mw-collapsed" id="mw-customcollapsible-' .. tostring(mw.uri.encode(page, 'WIKI')) .. '"'
end

local function RangColor(rang) -- эта функция возвращает цвет ранга (то же, что шаблон Rang/color)
    local srang = "/" .. rang .. "/"
    return (string.find(Rangs.Ich, srang, 1, true) and RangColors.Ich)
            or (string.find(Rangs.Osn, srang, 1, true) and RangColors.Osn)
            or (string.find(Rangs.Prom, srang, 1, true) and RangColors.Prom)
            or (string.find(Rangs.Bez, srang, 1, true) and RangColors.Bez)
            or ((rang == Rangs.Err) and RangColors.Err)
            or RangColors.Dop
end

local function NameString(args, last) -- форматирует название таксона
    local latlink = string.gsub(args.latin, " *|.*", "", 1)
    local latname = string.gsub(args.latin, ".*| *", "", 1)
    latname = Taxonomy_latin.latin { args = {latname, rang = args.rang, regnum = regnum}}
    local name = (args.name ~= "") and args.name or latname

    if last then
        return "'''" .. name .. "'''"
    elseif (args.monoaut == "") then
        return "[[" .. latlink .. "|" .. name .. "]]"
    else
        local aut = (args.monoaut == "1") and "" or " " .. Taxonomy_latin.author {args = {args.monoaut}}
        if args.name == "" then
            return "'''" .. name .. "'''" .. aut
        else
            return "'''" .. name .. "'''" .. " (" .. latname .. aut .. ")"
        end
    end
end

local function TaxString(args, last) -- форматирует строку классификации вида "Ранг: Таксон" (то же что шаблон TaxString)
	args.rang = mw.ustring.gsub(args.rang, ".", mw.ustring.upper, 1) -- на всякий случай первую букву делаем прописной
	local rang = (args.rang ~= "") and args.rang or Rangs.Err
    local latname = string.gsub(args.latin, ".*| *", "", 1)
    latname = Taxonomy_latin.latin { args = {latname, rang = args.rang, regnum = regnum}}
    local name = (args.name ~= "") and args.name or latname

	return "<tr " .. ((last or args.vis ~= "") and "" or RangClass(rang, args.page)) .. ">" ..
	        "<th scope='row' class='ts-Taxonomy-rang-label' style='color:" .. RangColor(rang) .. "'>" .. rang .. ":</th>" ..
	        "<td class='ts-Taxonomy-rang-name'>" ..
	            ((args.ext ~= "") and "†&nbsp;" or "") ..
	            NameString(args, last) ..
	            (args.ref or "") ..
	        "</td>" ..
	    "</tr>"
end

local function NoTaxTempl(taxon)
return 'нет [[Шаблон:Таксон#Система таксономической навигации|таксономического шаблона]] ' ..
    mw.getCurrentFrame():expandTemplate({title = 'RedTaxLink', args = {taxon}})
end

local function ErrorText(text)
return '<div class="ts-Taxonomy-error">ОШИБКА: ' .. text .. '</div>\n' ..
    ((mw.title.getCurrentTitle().namespace == 0) and "[[Категория:Википедия:Биологические статьи без таксошаблона]]" or "")
end

local function FormatOutput(text, ok, page)
	if not ok then return text end
    
	return (string.find(text, "mw-collapsible", 1, true)
            and '<span role="button" class="mw-customtoggle-' .. tostring(mw.uri.encode(page, 'WIKI')) .. '" style="border-bottom:1px dotted;">Показать/скрыть промежуточные ранги</span>'
            or ''
        ) .. text
end

local function getTaxPar(frame, taxon, parName)
    return mw.text.trim(frame:expandTemplate({title = taxon, args = {parName}}))
end

function p.TaxRecursion(frame)
    local i = 0
    local args = {}
    local res = ""
    local taxon = frame.args["latin"] or ""
    regnum = frame.args["regnum"]
    local pageName

    if (taxon == "") then
        return ErrorText("не заполнен параметр '''<big>latin</big>'''.")
    end

    local ok, parent
    local lastTemplate = mw.title.new("Шаблон:" .. taxon)
    if lastTemplate and lastTemplate.exists then
        ok, parent = pcall(getTaxPar, frame, taxon, "parent")
    end

    if ok then -- есть шаблон {{{latin}}}, берём оттуда
        pageName = parent
        args = {
        		  page = pageName,
        		 latin = getTaxPar(frame, taxon, "latin"),
                  rang = getTaxPar(frame, taxon, "rang"),                 
                   ext = getTaxPar(frame, taxon, "ext"),
                  name = getTaxPar(frame, taxon, "name"),
               }
    else -- нет шаблона {{{latin}}}, берём из параметров
        parent = frame.args["parent"] or ""
        pageName = parent
        args = {
        		  page = pageName,
        		 latin = frame.args["latin"],
                  rang = frame.args["rang"] or "",
                   ext = frame.args["Вымер"] or "",
                  name = frame.args["name"] or "",
               }
        if (parent == "") then
            if ((args.rang == "") or string.find(Rangs.Spec, "/" .. args.rang .. "/", 1, true)) then
                res = ErrorText("необходимо заполнить параметры '''<big>parent</big>''' и '''<big>rang</big>'''.")
            else
                res = ErrorText(NoTaxTempl(taxon) .. ". Заполните параметры '''<big>parent</big>''' и '''<big>rang</big>'''.")
            end
            return FormatOutput(res .. TaxString(args, "last"), false)
        end
    end

    res = TaxString(args, "last")

    local taxlist = {}
    while (parent ~= "Null") and (i < 100) do
        i = i + 1
        taxon = parent
        taxlist[taxon] = true
        ok, parent = pcall(getTaxPar, frame, taxon, "parent")
        if not ok then -- error: no template
            res = ErrorText(NoTaxTempl(taxon) .. ", который должен описывать систематическое положение таксона ''[[" .. taxon .. "]]''.") .. res
            return FormatOutput(res, false)
        end
        if taxlist[parent] then -- error: loop
            res = ErrorText("обнаружена петля — [[Шаблон:Таксон#Система таксономической навигации|таксономический шаблон]] {{[[Шаблон:" .. taxon .. "|" .. taxon .. "]]}} ссылается на свой подчинённый таксон.") .. res
            return FormatOutput(res, false)
        end
        args = {
        		    page = pageName,
        		   latin = getTaxPar(frame, taxon, "latin"),
                    rang = getTaxPar(frame, taxon, "rang"),
                     ext = getTaxPar(frame, taxon, "ext"),
                    name = getTaxPar(frame, taxon, "name"),
                 monoaut = getTaxPar(frame, taxon, "monoaut"),
                     ref = getTaxPar(frame, taxon, "ref"),
                     vis = getTaxPar(frame, taxon, "vis")
               }
        args.ref = (args.ref ~= "") and frame:extensionTag {name = "ref", content = args.ref}
        res = TaxString(args) .. res
    end

    return FormatOutput(res, ok, pageName)
end

return p